// SPDX-License-Identifier: GPL-2.0 or MIT
/*
 * Copyright (c) 2025 Red Hat.
 * Author: Jocelyn Falempe <jfalempe@redhat.com>
 *
 * KUNIT tests for drm panic
 */

#include <drm/drm_fourcc.h>
#include <drm/drm_panic.h>

#include <kunit/test.h>

#include <linux/units.h>
#include <linux/vmalloc.h>

/* Check the framebuffer color only if the panic colors are the default */
#if (CONFIG_DRM_PANIC_BACKGROUND_COLOR == 0 && \
	CONFIG_DRM_PANIC_FOREGROUND_COLOR == 0xffffff)

static void drm_panic_check_color_byte(struct kunit *test, u8 b)
{
	KUNIT_EXPECT_TRUE(test, (b == 0 || b == 0xff));
}
#else
static void drm_panic_check_color_byte(struct kunit *test, u8 b) {}
#endif

struct drm_test_mode {
	const int width;
	const int height;
	const u32 format;
	void (*draw_screen)(struct drm_scanout_buffer *sb);
	const char *fname;
};

/*
 * Run all tests for the 3 panic screens: user, kmsg and qr_code
 */
#define DRM_TEST_MODE_LIST(func) \
	DRM_PANIC_TEST_MODE(1024, 768, DRM_FORMAT_XRGB8888, func) \
	DRM_PANIC_TEST_MODE(300, 200, DRM_FORMAT_XRGB8888, func) \
	DRM_PANIC_TEST_MODE(1920, 1080, DRM_FORMAT_XRGB8888, func) \
	DRM_PANIC_TEST_MODE(1024, 768, DRM_FORMAT_RGB565, func) \
	DRM_PANIC_TEST_MODE(1024, 768, DRM_FORMAT_RGB888, func) \

#define DRM_PANIC_TEST_MODE(w, h, f, name) { \
	.width = w, \
	.height = h, \
	.format = f, \
	.draw_screen = draw_panic_screen_##name, \
	.fname = #name, \
	}, \

static const struct drm_test_mode drm_test_modes_cases[] = {
	DRM_TEST_MODE_LIST(user)
	DRM_TEST_MODE_LIST(kmsg)
#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
	DRM_TEST_MODE_LIST(qr_code)
#endif
};

#undef DRM_PANIC_TEST_MODE

static int drm_test_panic_init(struct kunit *test)
{
	struct drm_scanout_buffer *priv;

	priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
	KUNIT_ASSERT_NOT_NULL(test, priv);

	test->priv = priv;

	drm_panic_set_description("Kunit testing");

	return 0;
}

/*
 * Test drawing the panic screen, using a memory mapped framebuffer
 * Set the whole buffer to 0xa5, and then check that all pixels have been
 * written.
 */
static void drm_test_panic_screen_user_map(struct kunit *test)
{
	struct drm_scanout_buffer *sb = test->priv;
	const struct drm_test_mode *params = test->param_value;
	char *fb;
	int fb_size;
	int i;

	sb->format = drm_format_info(params->format);
	fb_size = params->width * params->height * sb->format->cpp[0];

	fb = vmalloc(fb_size);
	KUNIT_ASSERT_NOT_NULL(test, fb);

	memset(fb, 0xa5, fb_size);

	iosys_map_set_vaddr(&sb->map[0], fb);
	sb->width = params->width;
	sb->height = params->height;
	sb->pitch[0] = params->width * sb->format->cpp[0];

	params->draw_screen(sb);

	for (i = 0; i < fb_size; i++)
		drm_panic_check_color_byte(test, fb[i]);

	vfree(fb);
}

/*
 * Test drawing the panic screen, using a list of pages framebuffer
 * Set the whole buffer to 0xa5, and then check that all pixels have been
 * written.
 */
static void drm_test_panic_screen_user_page(struct kunit *test)
{
	struct drm_scanout_buffer *sb = test->priv;
	const struct drm_test_mode *params = test->param_value;
	int fb_size, p, i, npages;
	struct page **pages;
	u8 *vaddr;

	sb->format = drm_format_info(params->format);
	fb_size = params->width * params->height * sb->format->cpp[0];
	npages = DIV_ROUND_UP(fb_size, PAGE_SIZE);

	pages = kmalloc_objs(struct page *, npages);
	KUNIT_ASSERT_NOT_NULL(test, pages);

	for (p = 0; p < npages; p++) {
		pages[p] = alloc_page(GFP_KERNEL);
		if (!pages[p]) {
			npages = p - 1;
			KUNIT_FAIL(test, "Can't allocate page\n");
			goto free_pages;
		}
		vaddr = kmap_local_page(pages[p]);
		memset(vaddr, 0xa5, PAGE_SIZE);
		kunmap_local(vaddr);
	}
	sb->pages = pages;
	sb->width = params->width;
	sb->height = params->height;
	sb->pitch[0] = params->width * sb->format->cpp[0];

	params->draw_screen(sb);

	for (p = 0; p < npages; p++) {
		int bytes_in_page = (p == npages - 1) ? fb_size - p * PAGE_SIZE : PAGE_SIZE;

		vaddr = kmap_local_page(pages[p]);
		for (i = 0; i < bytes_in_page; i++)
			drm_panic_check_color_byte(test, vaddr[i]);

		kunmap_local(vaddr);
	}

free_pages:
	for (p = 0; p < npages; p++)
		__free_page(pages[p]);
	kfree(pages);
}

static void drm_test_panic_set_pixel(struct drm_scanout_buffer *sb,
				     unsigned int x,
				     unsigned int y,
				     u32 color)
{
	struct kunit *test = (struct kunit *)sb->private;

	KUNIT_ASSERT_TRUE(test, x < sb->width && y < sb->height);
}

/*
 * Test drawing the panic screen, using the set_pixel callback
 * Check that all calls to set_pixel() are within the framebuffer
 */
static void drm_test_panic_screen_user_set_pixel(struct kunit *test)
{
	struct drm_scanout_buffer *sb = test->priv;
	const struct drm_test_mode *params = test->param_value;

	sb->format = drm_format_info(params->format);
	sb->set_pixel = drm_test_panic_set_pixel;
	sb->width = params->width;
	sb->height = params->height;
	sb->private = test;

	params->draw_screen(sb);
}

static void drm_test_panic_desc(const struct drm_test_mode *t, char *desc)
{
	sprintf(desc, "Panic screen %s, mode: %d x %d \t%p4cc",
		t->fname, t->width, t->height, &t->format);
}

KUNIT_ARRAY_PARAM(drm_test_panic_screen_user_map, drm_test_modes_cases, drm_test_panic_desc);
KUNIT_ARRAY_PARAM(drm_test_panic_screen_user_page, drm_test_modes_cases, drm_test_panic_desc);
KUNIT_ARRAY_PARAM(drm_test_panic_screen_user_set_pixel, drm_test_modes_cases, drm_test_panic_desc);

static struct kunit_case drm_panic_screen_user_test[] = {
	KUNIT_CASE_PARAM(drm_test_panic_screen_user_map,
			 drm_test_panic_screen_user_map_gen_params),
	KUNIT_CASE_PARAM(drm_test_panic_screen_user_page,
			 drm_test_panic_screen_user_page_gen_params),
	KUNIT_CASE_PARAM(drm_test_panic_screen_user_set_pixel,
			 drm_test_panic_screen_user_set_pixel_gen_params),
	{ }
};

static struct kunit_suite drm_panic_suite = {
	.name = "drm_panic",
	.init = drm_test_panic_init,
	.test_cases = drm_panic_screen_user_test,
};

kunit_test_suite(drm_panic_suite);
