// SPDX-License-Identifier: GPL-2.0 AND MIT
/*
* Copyright © 2023 Intel Corporation
*/
#include <linux/delay.h>
#include <linux/kthread.h>
#include <drm/ttm/ttm_resource.h>
#include <drm/ttm/ttm_placement.h>
#include <drm/ttm/ttm_tt.h>
#include "ttm_kunit_helpers.h"
#include "ttm_mock_manager.h"
#define BO_SIZE SZ_4K
#define MANAGER_SIZE SZ_1M
static struct spinlock fence_lock;
struct ttm_bo_validate_test_case {
const char *description;
enum ttm_bo_type bo_type;
u32 mem_type;
bool with_ttm;
bool no_gpu_wait;
};
static struct ttm_placement *ttm_placement_kunit_init(struct kunit *test,
struct ttm_place *places,
unsigned int num_places)
{
struct ttm_placement *placement;
placement = kunit_kzalloc(test, sizeof(*placement), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, placement);
placement->num_placement = num_places;
placement->placement = places;
return placement;
}
static const char *fence_name(struct dma_fence *f)
{
return "ttm-bo-validate-fence";
}
static const struct dma_fence_ops fence_ops = {
.get_driver_name = fence_name,
.get_timeline_name = fence_name,
};
static struct dma_fence *alloc_mock_fence(struct kunit *test)
{
struct dma_fence *fence;
fence = kunit_kzalloc(test, sizeof(*fence), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, fence);
dma_fence_init(fence, &fence_ops, &fence_lock, 0, 0);
return fence;
}
static void dma_resv_kunit_active_fence_init(struct kunit *test,
struct dma_resv *resv,
enum dma_resv_usage usage)
{
struct dma_fence *fence;
fence = alloc_mock_fence(test);
dma_fence_enable_sw_signaling(fence);
dma_resv_lock(resv, NULL);
dma_resv_reserve_fences(resv, 1);
dma_resv_add_fence(resv, fence, usage);
dma_resv_unlock(resv);
}
static void ttm_bo_validate_case_desc(const struct ttm_bo_validate_test_case *t,
char *desc)
{
strscpy(desc, t->description, KUNIT_PARAM_DESC_SIZE);
}
static const struct ttm_bo_validate_test_case ttm_bo_type_cases[] = {
{
.description = "Buffer object for userspace",
.bo_type = ttm_bo_type_device,
},
{
.description = "Kernel buffer object",
.bo_type = ttm_bo_type_kernel,
},
{
.description = "Shared buffer object",
.bo_type = ttm_bo_type_sg,
},
};
KUNIT_ARRAY_PARAM(ttm_bo_types, ttm_bo_type_cases,
ttm_bo_validate_case_desc);
static void ttm_bo_init_reserved_sys_man(struct kunit *test)
{
const struct ttm_bo_validate_test_case *params = test->param_value;
struct ttm_test_devices *priv = test->priv;
enum ttm_bo_type bo_type = params->bo_type;
u32 size = ALIGN(BO_SIZE, PAGE_SIZE);
struct ttm_operation_ctx ctx = { };
struct ttm_placement *placement;
struct ttm_buffer_object *bo;
struct ttm_place *place;
int err;
bo = kunit_kzalloc(test, sizeof(*bo), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, bo);
place = ttm_place_kunit_init(test, TTM_PL_SYSTEM, 0);
placement = ttm_placement_kunit_init(test, place, 1);
drm_gem_private_object_init(priv->drm, &bo->base, size);
err = ttm_bo_init_reserved(priv->ttm_dev, bo, bo_type, placement,
PAGE_SIZE,