summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/ttm
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2022-09-06 11:56:03 +0300
committerDaniel Vetter <daniel.vetter@ffwll.ch>2022-09-06 11:56:04 +0300
commit8284bae723f025cb6a8431566757a3854a3c53eb (patch)
tree91c86c11413d12add21973c46b0a58f72ad103e0 /drivers/gpu/drm/ttm
parent2c2d7a67defa198a8b8148dbaddc9e5554efebc8 (diff)
parent8869fa666a9e6782c3c896c1fa57d65adca23249 (diff)
downloadlinux-8284bae723f025cb6a8431566757a3854a3c53eb.tar.xz
Merge tag 'drm-misc-next-2022-08-20-1' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for v6.1: UAPI Changes: Cross-subsystem Changes: - DMA-buf: documentation updates. - Assorted small fixes to vga16fb - Fix fbdev drivers to use the aperture helpers. - Make removal of conflicting drivers work correctly without fbdev enabled. Core Changes: - bridge, scheduler, dp-mst: Assorted small fixes. - Add more format helpers to fourcc, and use it to replace the cpp usage. - Add DRM_FORMAT_Cxx, DRM_FORMAT_Rxx (single channel), and DRM_FORMAT_Dxx ("darkness", inverted single channel) - Add packed AYUV8888 and XYUV8888 formats. - Assorted documentation updates. - Rename ttm_bo_init to ttm_bo_init_validate. - Allow TTM bo's to exist without backing store. - Convert drm selftests to kunit. - Add managed init functions for (panel) bridge, crtc, encoder and connector. - Fix endianness handling in various format conversion helpers. - Make tests pass on big-endian platforms, and add test for rgb888 -> rgb565 - Move DRM_PLANE_HELPER_NO_SCALING to atomic helpers and rename, so drm_plane_helper is no longer needed in most drivers. - Use idr_init_base instead of idr_init. - Rename FB and GEM CMA helpers to DMA helpers. - Rework XRGB8888 related conversion helpers, and add drm_fb_blit() that takes a iosys_map. Make drm_fb_memcpy take an iosys_map too. - Move edid luminance calculation to core, and use it in i915. Driver Changes: - bridge/{adv7511,ti-sn65dsi86,parade-ps8640}, panel/{simple,nt35510,tc358767}, nouveau, sun4i, mipi-dsi, mgag200, bochs, arm, komeda, vmwgfx, pl111: Assorted small fixes and doc updates. - vc4: Rework hdmi power up, and depend on PM. - panel/simple: Add Samsung LTL101AL01. - ingenic: Add JZ4760(B) support, avoid a modeset when sharpness property is unchanged, and use the new PM ops. - Revert some amdgpu commits that cause garbaged graphics when starting X, and reapply them with the real problem fixed. - Completely rework vc4 init to use managed helpers. - Rename via_drv to via_dri1, and move all stuff there only used by the dri1 implementation in preperation for atomic modeset. - Use regmap bulk write in ssd130x. - Power sequence and clock updates to it6505. - Split panel-sitrox-st7701 init sequence and rework mode programming code. - virtio: Improve error and edge conditions handling, and convert to use managed helpers. - Add Samsung LTL101AL01, B120XAN01.0, R140NWF5 RH, DMT028VGHMCMI-1A T, panels. - Add generic fbdev support to komeda. - Split mgag200 modeset handling to make it more model-specific. - Convert simpledrm to use atomic helpers. - Improve udl suspend/disconnect handling. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/f0c71766-61e8-19b7-763a-5fbcdefc633d@linux.intel.com
Diffstat (limited to 'drivers/gpu/drm/ttm')
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c163
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_util.c7
2 files changed, 116 insertions, 54 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 97184c333526..590110fdf59c 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -117,12 +117,13 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
struct ttm_operation_ctx *ctx,
struct ttm_place *hop)
{
- struct ttm_resource_manager *old_man, *new_man;
struct ttm_device *bdev = bo->bdev;
+ bool old_use_tt, new_use_tt;
int ret;
- old_man = ttm_manager_type(bdev, bo->resource->mem_type);
- new_man = ttm_manager_type(bdev, mem->mem_type);
+ old_use_tt = bo->resource &&
+ ttm_manager_type(bdev, bo->resource->mem_type)->use_tt;
+ new_use_tt = ttm_manager_type(bdev, mem->mem_type)->use_tt;
ttm_bo_unmap_virtual(bo);
@@ -130,11 +131,11 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
* Create and bind a ttm if required.
*/
- if (new_man->use_tt) {
+ if (new_use_tt) {
/* Zero init the new TTM structure if the old location should
* have used one as well.
*/
- ret = ttm_tt_create(bo, old_man->use_tt);
+ ret = ttm_tt_create(bo, old_use_tt);
if (ret)
goto out_err;
@@ -160,8 +161,7 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
return 0;
out_err:
- new_man = ttm_manager_type(bdev, bo->resource->mem_type);
- if (!new_man->use_tt)
+ if (!old_use_tt)
ttm_bo_tt_destroy(bo);
return ret;
@@ -904,7 +904,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
/*
* Check whether we need to move buffer.
*/
- if (!ttm_resource_compat(bo->resource, placement)) {
+ if (!bo->resource || !ttm_resource_compat(bo->resource, placement)) {
ret = ttm_bo_move_buffer(bo, placement, ctx);
if (ret)
return ret;
@@ -921,36 +921,61 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
}
EXPORT_SYMBOL(ttm_bo_validate);
-int ttm_bo_init_reserved(struct ttm_device *bdev,
- struct ttm_buffer_object *bo,
- size_t size,
- enum ttm_bo_type type,
- struct ttm_placement *placement,
- uint32_t page_alignment,
- struct ttm_operation_ctx *ctx,
- struct sg_table *sg,
- struct dma_resv *resv,
+/**
+ * ttm_bo_init_reserved
+ *
+ * @bdev: Pointer to a ttm_device struct.
+ * @bo: Pointer to a ttm_buffer_object to be initialized.
+ * @type: Requested type of buffer object.
+ * @placement: Initial placement for buffer object.
+ * @alignment: Data alignment in pages.
+ * @ctx: TTM operation context for memory allocation.
+ * @sg: Scatter-gather table.
+ * @resv: Pointer to a dma_resv, or NULL to let ttm allocate one.
+ * @destroy: Destroy function. Use NULL for kfree().
+ *
+ * This function initializes a pre-allocated struct ttm_buffer_object.
+ * As this object may be part of a larger structure, this function,
+ * together with the @destroy function, enables driver-specific objects
+ * derived from a ttm_buffer_object.
+ *
+ * On successful return, the caller owns an object kref to @bo. The kref and
+ * list_kref are usually set to 1, but note that in some situations, other
+ * tasks may already be holding references to @bo as well.
+ * Furthermore, if resv == NULL, the buffer's reservation lock will be held,
+ * and it is the caller's responsibility to call ttm_bo_unreserve.
+ *
+ * If a failure occurs, the function will call the @destroy function. Thus,
+ * after a failure, dereferencing @bo is illegal and will likely cause memory
+ * corruption.
+ *
+ * Returns
+ * -ENOMEM: Out of memory.
+ * -EINVAL: Invalid placement flags.
+ * -ERESTARTSYS: Interrupted by signal while sleeping waiting for resources.
+ */
+int ttm_bo_init_reserved(struct ttm_device *bdev, struct ttm_buffer_object *bo,
+ enum ttm_bo_type type, struct ttm_placement *placement,
+ uint32_t alignment, struct ttm_operation_ctx *ctx,
+ struct sg_table *sg, struct dma_resv *resv,
void (*destroy) (struct ttm_buffer_object *))
{
static const struct ttm_place sys_mem = { .mem_type = TTM_PL_SYSTEM };
- bool locked;
int ret;
- bo->destroy = destroy;
kref_init(&bo->kref);
INIT_LIST_HEAD(&bo->ddestroy);
bo->bdev = bdev;
bo->type = type;
- bo->page_alignment = page_alignment;
+ bo->page_alignment = alignment;
+ bo->destroy = destroy;
bo->pin_count = 0;
bo->sg = sg;
bo->bulk_move = NULL;
- if (resv) {
+ if (resv)
bo->base.resv = resv;
- dma_resv_assert_held(bo->base.resv);
- } else {
+ else
bo->base.resv = &bo->base._resv;
- }
atomic_inc(&ttm_glob.bo_count);
ret = ttm_resource_alloc(bo, &sys_mem, &bo->resource);
@@ -963,50 +988,84 @@ int ttm_bo_init_reserved(struct ttm_device *bdev,
* For ttm_bo_type_device buffers, allocate
* address space from the device.
*/
- if (bo->type == ttm_bo_type_device ||
- bo->type == ttm_bo_type_sg)
+ if (bo->type == ttm_bo_type_device || bo->type == ttm_bo_type_sg) {
ret = drm_vma_offset_add(bdev->vma_manager, &bo->base.vma_node,
- bo->resource->num_pages);
+ PFN_UP(bo->base.size));
+ if (ret)
+ goto err_put;
+ }
/* passed reservation objects should already be locked,
* since otherwise lockdep will be angered in radeon.
*/
- if (!resv) {
- locked = dma_resv_trylock(bo->base.resv);
- WARN_ON(!locked);
- }
+ if (!resv)
+ WARN_ON(!dma_resv_trylock(bo->base.resv));
+ else
+ dma_resv_assert_held(resv);
- if (likely(!ret))
- ret = ttm_bo_validate(bo, placement, ctx);
+ ret = ttm_bo_validate(bo, placement, ctx);
+ if (unlikely(ret))
+ goto err_unlock;
- if (unlikely(ret)) {
- if (!resv)
- ttm_bo_unreserve(bo);
+ return 0;
- ttm_bo_put(bo);
- return ret;
- }
+err_unlock:
+ if (!resv)
+ dma_resv_unlock(bo->base.resv);
+err_put:
+ ttm_bo_put(bo);
return ret;
}
EXPORT_SYMBOL(ttm_bo_init_reserved);
-int ttm_bo_init(struct ttm_device *bdev,
- struct ttm_buffer_object *bo,
- size_t size,
- enum ttm_bo_type type,
- struct ttm_placement *placement,
- uint32_t page_alignment,
- bool interruptible,
- struct sg_table *sg,
- struct dma_resv *resv,
- void (*destroy) (struct ttm_buffer_object *))
+/**
+ * ttm_bo_init_validate
+ *
+ * @bdev: Pointer to a ttm_device struct.
+ * @bo: Pointer to a ttm_buffer_object to be initialized.
+ * @type: Requested type of buffer object.
+ * @placement: Initial placement for buffer object.
+ * @alignment: Data alignment in pages.
+ * @interruptible: If needing to sleep to wait for GPU resources,
+ * sleep interruptible.
+ * pinned in physical memory. If this behaviour is not desired, this member
+ * holds a pointer to a persistent shmem object. Typically, this would
+ * point to the shmem object backing a GEM object if TTM is used to back a
+ * GEM user interface.
+ * @sg: Scatter-gather table.
+ * @resv: Pointer to a dma_resv, or NULL to let ttm allocate one.
+ * @destroy: Destroy function. Use NULL for kfree().
+ *
+ * This function initializes a pre-allocated struct ttm_buffer_object.
+ * As this object may be part of a larger structure, this function,
+ * together with the @destroy function,
+ * enables driver-specific objects derived from a ttm_buffer_object.
+ *
+ * On successful return, the caller owns an object kref to @bo. The kref and
+ * list_kref are usually set to 1, but note that in some situations, other
+ * tasks may already be holding references to @bo as well.
+ *
+ * If a failure occurs, the function will call the @destroy function, Thus,
+ * after a failure, dereferencing @bo is illegal and will likely cause memory
+ * corruption.
+ *
+ * Returns
+ * -ENOMEM: Out of memory.
+ * -EINVAL: Invalid placement flags.
+ * -ERESTARTSYS: Interrupted by signal while sleeping waiting for resources.
+ */
+int ttm_bo_init_validate(struct ttm_device *bdev, struct ttm_buffer_object *bo,
+ enum ttm_bo_type type, struct ttm_placement *placement,
+ uint32_t alignment, bool interruptible,
+ struct sg_table *sg, struct dma_resv *resv,
+ void (*destroy) (struct ttm_buffer_object *))
{
struct ttm_operation_ctx ctx = { interruptible, false };
int ret;
- ret = ttm_bo_init_reserved(bdev, bo, size, type, placement,
- page_alignment, &ctx, sg, resv, destroy);
+ ret = ttm_bo_init_reserved(bdev, bo, type, placement, alignment, &ctx,
+ sg, resv, destroy);
if (ret)
return ret;
@@ -1015,7 +1074,7 @@ int ttm_bo_init(struct ttm_device *bdev,
return 0;
}
-EXPORT_SYMBOL(ttm_bo_init);
+EXPORT_SYMBOL(ttm_bo_init_validate);
/*
* buffer object vm functions.
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
index 1cbfb00c1d65..1530982338e9 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -137,8 +137,7 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
ttm_manager_type(bo->bdev, dst_mem->mem_type);
struct ttm_tt *ttm = bo->ttm;
struct ttm_resource *src_mem = bo->resource;
- struct ttm_resource_manager *src_man =
- ttm_manager_type(bdev, src_mem->mem_type);
+ struct ttm_resource_manager *src_man;
union {
struct ttm_kmap_iter_tt tt;
struct ttm_kmap_iter_linear_io io;
@@ -147,6 +146,10 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
bool clear;
int ret = 0;
+ if (!src_mem)
+ return 0;
+
+ src_man = ttm_manager_type(bdev, src_mem->mem_type);
if (ttm && ((ttm->page_flags & TTM_TT_FLAG_SWAPPED) ||
dst_man->use_tt)) {
ret = ttm_tt_populate(bdev, ttm, ctx);