1e3912d09SKarolina Stolarek // SPDX-License-Identifier: GPL-2.0 AND MIT
2e3912d09SKarolina Stolarek /*
3e3912d09SKarolina Stolarek  * Copyright © 2023 Intel Corporation
4e3912d09SKarolina Stolarek  */
5e3912d09SKarolina Stolarek #include <drm/ttm/ttm_resource.h>
6e3912d09SKarolina Stolarek #include <drm/ttm/ttm_device.h>
7e3912d09SKarolina Stolarek #include <drm/ttm/ttm_placement.h>
8e3912d09SKarolina Stolarek 
9e3912d09SKarolina Stolarek #include "ttm_kunit_helpers.h"
10e3912d09SKarolina Stolarek 
1124ac009eSKarolina Stolarek struct ttm_device_test_case {
1224ac009eSKarolina Stolarek 	const char *description;
1324ac009eSKarolina Stolarek 	bool use_dma_alloc;
1424ac009eSKarolina Stolarek 	bool use_dma32;
1524ac009eSKarolina Stolarek 	bool pools_init_expected;
1624ac009eSKarolina Stolarek };
1724ac009eSKarolina Stolarek 
ttm_device_init_basic(struct kunit * test)18e3912d09SKarolina Stolarek static void ttm_device_init_basic(struct kunit *test)
19e3912d09SKarolina Stolarek {
20e3912d09SKarolina Stolarek 	struct ttm_test_devices *priv = test->priv;
21e3912d09SKarolina Stolarek 	struct ttm_device *ttm_dev;
22e3912d09SKarolina Stolarek 	struct ttm_resource_manager *ttm_sys_man;
23e3912d09SKarolina Stolarek 	int err;
24e3912d09SKarolina Stolarek 
25e3912d09SKarolina Stolarek 	ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
26e3912d09SKarolina Stolarek 	KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
27e3912d09SKarolina Stolarek 
28e3912d09SKarolina Stolarek 	err = ttm_device_kunit_init(priv, ttm_dev, false, false);
29e3912d09SKarolina Stolarek 	KUNIT_ASSERT_EQ(test, err, 0);
30e3912d09SKarolina Stolarek 
31e3912d09SKarolina Stolarek 	KUNIT_EXPECT_PTR_EQ(test, ttm_dev->funcs, &ttm_dev_funcs);
32e3912d09SKarolina Stolarek 	KUNIT_ASSERT_NOT_NULL(test, ttm_dev->wq);
33e3912d09SKarolina Stolarek 	KUNIT_ASSERT_NOT_NULL(test, ttm_dev->man_drv[TTM_PL_SYSTEM]);
34e3912d09SKarolina Stolarek 
35e3912d09SKarolina Stolarek 	ttm_sys_man = &ttm_dev->sysman;
36e3912d09SKarolina Stolarek 	KUNIT_ASSERT_NOT_NULL(test, ttm_sys_man);
37e3912d09SKarolina Stolarek 	KUNIT_EXPECT_TRUE(test, ttm_sys_man->use_tt);
38e3912d09SKarolina Stolarek 	KUNIT_EXPECT_TRUE(test, ttm_sys_man->use_type);
39e3912d09SKarolina Stolarek 	KUNIT_ASSERT_NOT_NULL(test, ttm_sys_man->func);
40e3912d09SKarolina Stolarek 
41e3912d09SKarolina Stolarek 	KUNIT_EXPECT_PTR_EQ(test, ttm_dev->dev_mapping,
42e3912d09SKarolina Stolarek 			    priv->drm->anon_inode->i_mapping);
43e3912d09SKarolina Stolarek 
44e3912d09SKarolina Stolarek 	ttm_device_fini(ttm_dev);
45e3912d09SKarolina Stolarek }
46e3912d09SKarolina Stolarek 
ttm_device_init_multiple(struct kunit * test)4724ac009eSKarolina Stolarek static void ttm_device_init_multiple(struct kunit *test)
4824ac009eSKarolina Stolarek {
4924ac009eSKarolina Stolarek 	struct ttm_test_devices *priv = test->priv;
5024ac009eSKarolina Stolarek 	struct ttm_device *ttm_devs;
5124ac009eSKarolina Stolarek 	unsigned int i, num_dev = 3;
5224ac009eSKarolina Stolarek 	int err;
5324ac009eSKarolina Stolarek 
5424ac009eSKarolina Stolarek 	ttm_devs = kunit_kcalloc(test, num_dev, sizeof(*ttm_devs), GFP_KERNEL);
5524ac009eSKarolina Stolarek 	KUNIT_ASSERT_NOT_NULL(test, ttm_devs);
5624ac009eSKarolina Stolarek 
5724ac009eSKarolina Stolarek 	for (i = 0; i < num_dev; i++) {
5824ac009eSKarolina Stolarek 		err = ttm_device_kunit_init(priv, &ttm_devs[i], false, false);
5924ac009eSKarolina Stolarek 		KUNIT_ASSERT_EQ(test, err, 0);
6024ac009eSKarolina Stolarek 
6124ac009eSKarolina Stolarek 		KUNIT_EXPECT_PTR_EQ(test, ttm_devs[i].dev_mapping,
6224ac009eSKarolina Stolarek 				    priv->drm->anon_inode->i_mapping);
6324ac009eSKarolina Stolarek 		KUNIT_ASSERT_NOT_NULL(test, ttm_devs[i].wq);
6424ac009eSKarolina Stolarek 		KUNIT_EXPECT_PTR_EQ(test, ttm_devs[i].funcs, &ttm_dev_funcs);
6524ac009eSKarolina Stolarek 		KUNIT_ASSERT_NOT_NULL(test, ttm_devs[i].man_drv[TTM_PL_SYSTEM]);
6624ac009eSKarolina Stolarek 	}
6724ac009eSKarolina Stolarek 
6824ac009eSKarolina Stolarek 	KUNIT_ASSERT_EQ(test, list_count_nodes(&ttm_devs[0].device_list), num_dev);
6924ac009eSKarolina Stolarek 
7024ac009eSKarolina Stolarek 	for (i = 0; i < num_dev; i++)
7124ac009eSKarolina Stolarek 		ttm_device_fini(&ttm_devs[i]);
7224ac009eSKarolina Stolarek }
7324ac009eSKarolina Stolarek 
ttm_device_fini_basic(struct kunit * test)7424ac009eSKarolina Stolarek static void ttm_device_fini_basic(struct kunit *test)
7524ac009eSKarolina Stolarek {
7624ac009eSKarolina Stolarek 	struct ttm_test_devices *priv = test->priv;
7724ac009eSKarolina Stolarek 	struct ttm_device *ttm_dev;
7824ac009eSKarolina Stolarek 	struct ttm_resource_manager *man;
7924ac009eSKarolina Stolarek 	int err;
8024ac009eSKarolina Stolarek 
8124ac009eSKarolina Stolarek 	ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
8224ac009eSKarolina Stolarek 	KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
8324ac009eSKarolina Stolarek 
8424ac009eSKarolina Stolarek 	err = ttm_device_kunit_init(priv, ttm_dev, false, false);
8524ac009eSKarolina Stolarek 	KUNIT_ASSERT_EQ(test, err, 0);
8624ac009eSKarolina Stolarek 
8724ac009eSKarolina Stolarek 	man = ttm_manager_type(ttm_dev, TTM_PL_SYSTEM);
8824ac009eSKarolina Stolarek 	KUNIT_ASSERT_NOT_NULL(test, man);
8924ac009eSKarolina Stolarek 
9024ac009eSKarolina Stolarek 	ttm_device_fini(ttm_dev);
9124ac009eSKarolina Stolarek 
9224ac009eSKarolina Stolarek 	KUNIT_ASSERT_FALSE(test, man->use_type);
9324ac009eSKarolina Stolarek 	KUNIT_ASSERT_TRUE(test, list_empty(&man->lru[0]));
9424ac009eSKarolina Stolarek 	KUNIT_ASSERT_NULL(test, ttm_dev->man_drv[TTM_PL_SYSTEM]);
9524ac009eSKarolina Stolarek }
9624ac009eSKarolina Stolarek 
ttm_device_init_no_vma_man(struct kunit * test)9724ac009eSKarolina Stolarek static void ttm_device_init_no_vma_man(struct kunit *test)
9824ac009eSKarolina Stolarek {
9924ac009eSKarolina Stolarek 	struct ttm_test_devices *priv = test->priv;
10024ac009eSKarolina Stolarek 	struct drm_device *drm = priv->drm;
10124ac009eSKarolina Stolarek 	struct ttm_device *ttm_dev;
10224ac009eSKarolina Stolarek 	struct drm_vma_offset_manager *vma_man;
10324ac009eSKarolina Stolarek 	int err;
10424ac009eSKarolina Stolarek 
10524ac009eSKarolina Stolarek 	ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
10624ac009eSKarolina Stolarek 	KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
10724ac009eSKarolina Stolarek 
10824ac009eSKarolina Stolarek 	/* Let's pretend there's no VMA manager allocated */
10924ac009eSKarolina Stolarek 	vma_man = drm->vma_offset_manager;
11024ac009eSKarolina Stolarek 	drm->vma_offset_manager = NULL;
11124ac009eSKarolina Stolarek 
11224ac009eSKarolina Stolarek 	err = ttm_device_kunit_init(priv, ttm_dev, false, false);
11324ac009eSKarolina Stolarek 	KUNIT_EXPECT_EQ(test, err, -EINVAL);
11424ac009eSKarolina Stolarek 
11524ac009eSKarolina Stolarek 	/* Bring the manager back for a graceful cleanup */
11624ac009eSKarolina Stolarek 	drm->vma_offset_manager = vma_man;
11724ac009eSKarolina Stolarek }
11824ac009eSKarolina Stolarek 
11924ac009eSKarolina Stolarek static const struct ttm_device_test_case ttm_device_cases[] = {
12024ac009eSKarolina Stolarek 	{
12124ac009eSKarolina Stolarek 		.description = "No DMA allocations, no DMA32 required",
12224ac009eSKarolina Stolarek 		.use_dma_alloc = false,
12324ac009eSKarolina Stolarek 		.use_dma32 = false,
12424ac009eSKarolina Stolarek 		.pools_init_expected = false,
12524ac009eSKarolina Stolarek 	},
12624ac009eSKarolina Stolarek 	{
12724ac009eSKarolina Stolarek 		.description = "DMA allocations, DMA32 required",
12824ac009eSKarolina Stolarek 		.use_dma_alloc = true,
12924ac009eSKarolina Stolarek 		.use_dma32 = true,
13024ac009eSKarolina Stolarek 		.pools_init_expected = true,
13124ac009eSKarolina Stolarek 	},
13224ac009eSKarolina Stolarek 	{
13324ac009eSKarolina Stolarek 		.description = "No DMA allocations, DMA32 required",
13424ac009eSKarolina Stolarek 		.use_dma_alloc = false,
13524ac009eSKarolina Stolarek 		.use_dma32 = true,
13624ac009eSKarolina Stolarek 		.pools_init_expected = false,
13724ac009eSKarolina Stolarek 	},
13824ac009eSKarolina Stolarek 	{
13924ac009eSKarolina Stolarek 		.description = "DMA allocations, no DMA32 required",
14024ac009eSKarolina Stolarek 		.use_dma_alloc = true,
14124ac009eSKarolina Stolarek 		.use_dma32 = false,
14224ac009eSKarolina Stolarek 		.pools_init_expected = true,
14324ac009eSKarolina Stolarek 	},
14424ac009eSKarolina Stolarek };
14524ac009eSKarolina Stolarek 
ttm_device_case_desc(const struct ttm_device_test_case * t,char * desc)14624ac009eSKarolina Stolarek static void ttm_device_case_desc(const struct ttm_device_test_case *t, char *desc)
14724ac009eSKarolina Stolarek {
14824ac009eSKarolina Stolarek 	strscpy(desc, t->description, KUNIT_PARAM_DESC_SIZE);
14924ac009eSKarolina Stolarek }
15024ac009eSKarolina Stolarek 
15124ac009eSKarolina Stolarek KUNIT_ARRAY_PARAM(ttm_device, ttm_device_cases, ttm_device_case_desc);
15224ac009eSKarolina Stolarek 
ttm_device_init_pools(struct kunit * test)15324ac009eSKarolina Stolarek static void ttm_device_init_pools(struct kunit *test)
15424ac009eSKarolina Stolarek {
15524ac009eSKarolina Stolarek 	struct ttm_test_devices *priv = test->priv;
15624ac009eSKarolina Stolarek 	const struct ttm_device_test_case *params = test->param_value;
15724ac009eSKarolina Stolarek 	struct ttm_device *ttm_dev;
15824ac009eSKarolina Stolarek 	struct ttm_pool *pool;
15924ac009eSKarolina Stolarek 	struct ttm_pool_type pt;
16024ac009eSKarolina Stolarek 	int err;
16124ac009eSKarolina Stolarek 
16224ac009eSKarolina Stolarek 	ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL);
16324ac009eSKarolina Stolarek 	KUNIT_ASSERT_NOT_NULL(test, ttm_dev);
16424ac009eSKarolina Stolarek 
16524ac009eSKarolina Stolarek 	err = ttm_device_kunit_init(priv, ttm_dev,
16624ac009eSKarolina Stolarek 				    params->use_dma_alloc,
16724ac009eSKarolina Stolarek 				    params->use_dma32);
16824ac009eSKarolina Stolarek 	KUNIT_ASSERT_EQ(test, err, 0);
16924ac009eSKarolina Stolarek 
17024ac009eSKarolina Stolarek 	pool = &ttm_dev->pool;
17124ac009eSKarolina Stolarek 	KUNIT_ASSERT_NOT_NULL(test, pool);
17224ac009eSKarolina Stolarek 	KUNIT_EXPECT_PTR_EQ(test, pool->dev, priv->dev);
17324ac009eSKarolina Stolarek 	KUNIT_EXPECT_EQ(test, pool->use_dma_alloc, params->use_dma_alloc);
17424ac009eSKarolina Stolarek 	KUNIT_EXPECT_EQ(test, pool->use_dma32, params->use_dma32);
17524ac009eSKarolina Stolarek 
17624ac009eSKarolina Stolarek 	if (params->pools_init_expected) {
17724ac009eSKarolina Stolarek 		for (int i = 0; i < TTM_NUM_CACHING_TYPES; ++i) {
178ded1ffeaSKirill A. Shutemov 			for (int j = 0; j < NR_PAGE_ORDERS; ++j) {
17924ac009eSKarolina Stolarek 				pt = pool->caching[i].orders[j];
18024ac009eSKarolina Stolarek 				KUNIT_EXPECT_PTR_EQ(test, pt.pool, pool);
18124ac009eSKarolina Stolarek 				KUNIT_EXPECT_EQ(test, pt.caching, i);
18224ac009eSKarolina Stolarek 				KUNIT_EXPECT_EQ(test, pt.order, j);
18324ac009eSKarolina Stolarek 
18424ac009eSKarolina Stolarek 				if (params->use_dma_alloc)
18524ac009eSKarolina Stolarek 					KUNIT_ASSERT_FALSE(test,
18624ac009eSKarolina Stolarek 							   list_empty(&pt.pages));
18724ac009eSKarolina Stolarek 			}
18824ac009eSKarolina Stolarek 		}
18924ac009eSKarolina Stolarek 	}
19024ac009eSKarolina Stolarek 
19124ac009eSKarolina Stolarek 	ttm_device_fini(ttm_dev);
19224ac009eSKarolina Stolarek }
19324ac009eSKarolina Stolarek 
194e3912d09SKarolina Stolarek static struct kunit_case ttm_device_test_cases[] = {
195e3912d09SKarolina Stolarek 	KUNIT_CASE(ttm_device_init_basic),
19624ac009eSKarolina Stolarek 	KUNIT_CASE(ttm_device_init_multiple),
19724ac009eSKarolina Stolarek 	KUNIT_CASE(ttm_device_fini_basic),
19824ac009eSKarolina Stolarek 	KUNIT_CASE(ttm_device_init_no_vma_man),
19924ac009eSKarolina Stolarek 	KUNIT_CASE_PARAM(ttm_device_init_pools, ttm_device_gen_params),
200e3912d09SKarolina Stolarek 	{}
201e3912d09SKarolina Stolarek };
202e3912d09SKarolina Stolarek 
203e3912d09SKarolina Stolarek static struct kunit_suite ttm_device_test_suite = {
204e3912d09SKarolina Stolarek 	.name = "ttm_device",
205e3912d09SKarolina Stolarek 	.init = ttm_test_devices_init,
206e3912d09SKarolina Stolarek 	.exit = ttm_test_devices_fini,
207e3912d09SKarolina Stolarek 	.test_cases = ttm_device_test_cases,
208e3912d09SKarolina Stolarek };
209e3912d09SKarolina Stolarek 
210e3912d09SKarolina Stolarek kunit_test_suites(&ttm_device_test_suite);
211e3912d09SKarolina Stolarek 
212e3912d09SKarolina Stolarek MODULE_LICENSE("GPL");
213