/*
 * SPDX-License-Identifier: MIT
 *
 * Copyright © 2017 Intel Corporation
 */

#include <linux/prime_numbers.h>

#include "gt/intel_engine_pm.h"
#include "gt/intel_gpu_commands.h"
#include "gt/intel_gt.h"
#include "gt/intel_gt_pm.h"
#include "gt/intel_ring.h"

#include "i915_selftest.h"
#include "selftests/i915_random.h"

struct context {
	struct drm_i915_gem_object *obj;
	struct intel_engine_cs *engine;
};

static int cpu_set(struct context *ctx, unsigned long offset, u32 v)
{
	unsigned int needs_clflush;
	struct page *page;
	void *map;
	u32 *cpu;
	int err;

	i915_gem_object_lock(ctx->obj, NULL);
	err = i915_gem_object_prepare_write(ctx->obj, &needs_clflush);
	if (err)
		goto out;

	page = i915_gem_object_get_page(ctx->obj, offset >> PAGE_SHIFT);
	map = kmap_atomic(page);
	cpu = map + offset_in_page(offset);

	if (needs_clflush & CLFLUSH_BEFORE)
		drm_clflush_virt_range(cpu, sizeof(*cpu));

	*cpu = v;

	if (needs_clflush & CLFLUSH_AFTER)
		drm_clflush_virt_range(cpu, sizeof(*cpu));

	kunmap_atomic(map);
	i915_gem_object_finish_access(ctx->obj);

out:
	i915_gem_object_unlock(ctx->obj);
	return err;
}

static int cpu_get(struct context *ctx, unsigned long offset, u32 *v)
{
	unsigned int needs_clflush;
	struct page *page;
	void *map;
	u32 *cpu;
	int err;

	i915_gem_object_lock(ctx->obj, NULL);
	err = i915_gem_object_prepare_read(ctx->obj, &needs_clflush);
	if (err)
		goto out;

	page = i915_gem_object_get_page(ctx->obj, offset >> PAGE_SHIFT);
	map = kmap_atomic(page);
	cpu = map + offset_in_page(offset);

	if (needs_clflush & CLFLUSH_BEFORE)
		drm_clflush_virt_range(cpu, sizeof(*cpu));

	*v = *cpu;

	kunmap_atomic(map);
	i915_gem_object_finish_access(ctx->obj);

out:
	i915_gem_object_unlock(ctx->obj);
	return err;
}

static int gtt_set(struct context *ctx, unsigned long offset, u32 v)
{
	struct i915_vma *vma;
	u32 __iomem *map;
	int err = 0;

	i915_gem_object_lock(ctx->obj, NULL);
	err = i915_gem_object_set_to_gtt_domain(ctx->obj, true);
	i915_gem_object_unlock(ctx->obj);
	if (err)
		return err;

	vma = i915_gem_object_ggtt_pin(ctx->obj, NULL, 0, 0, PIN_MAPPABLE);
	if (IS_ERR(vma))
		return PTR_ERR(vma);

	intel_gt_pm_get(vma->vm->gt);

	map = i915_vma_pin_iomap(vma);
	i915_vma_unpin(vma);
	if (IS_ERR(map)) {
		err = PTR_ERR(map);
		goto out_rpm;
	}

	iowrite32(v, &map[offset / sizeof(*map)]);
	i915_vma_unpin_iomap(vma);

out_rpm:
	intel_gt_pm_put(vma->vm->gt);
	return err;
}

static int gtt_get(struct context *ctx, unsigned long offset, u32 *v)
{
	struct i915_vma *vma;
	u32 __iomem *map;
	int err = 0;

	i915_gem_object_lock(ctx->obj, NULL);
	err = i915_gem_object_set_to_gtt_domain(ctx->obj, false);
	i915_gem_object_unlock(ctx->obj);
	if (err)
		return err;

	vma = i915_gem_object_ggtt_pin(ctx->obj, NULL, 0, 0, PIN_MAPPABLE);
	if (IS_ERR(vma))
		return PTR_ERR(vma);

	intel_gt_pm_get(vma->vm->gt);

	map = i915_vma_pin_iomap(vma);
	i915_vma_unpin(vma);
	if (IS_ERR(map)) {
		err = PTR_ERR(map);
		goto out_rpm;
	}

	*v = ioread32(&map[offset / sizeof(*map)]);
	i915_vma_unpin_iomap(vma);

out_rpm:
	intel_gt_pm_put(vma->vm->gt);
	return err;
}

static int wc_set(struct context *ctx, unsigned long offset, u32 v)
{
	u32 *map;
	int err;

	i915_gem_object_lock(ctx->obj, NULL);
	err = i915_gem_object_set_to_wc_domain(ctx->obj, true);
	i915_gem_object_unlock(ctx->obj);
	if (err)
		return err;

	map = i915_gem_object_pin_map_unlocked(ctx->obj, I915_MAP_WC);
	if (IS_ERR(map))
		return PTR_ERR(map);

	map[offset / sizeof(*map)] = v;

	__i915_gem_object_flush_map(ctx->obj, offset, sizeof(*map));
	i915_gem_object_unpin_map(ctx->obj);

	return 0;
}

static int wc_get(struct context *ctx, unsigned long offset, u32 *v)
{
	u32 *map;
	int err;

	i915_gem_object_lock(ctx->obj, NULL);
	err = i915_gem_object_set_to_wc_domain(ctx->obj, false);
	i915_gem_object_unlock(ctx->obj);
	if (err)
		return err;

	map = i915_gem_object_pin_map_unlocked(ctx->obj, I915_MAP_WC);
	if (IS_ERR(map))
		return PTR_ERR(map);

	*v = map[offset / sizeof(*map)];
	i915_gem_object_unpin_map(ctx->obj);

	return 0;
}

static int gpu_set(struct context *ctx, unsigned long offset, u32 v)
{
	struct i915_request *rq;
	struct i915_vma *vma;
	u32 *cs;
	int err;

	vma = i915_gem_object_ggtt_pin(ctx->obj, NULL, 0, 0, 0);
	if (IS_ERR(vma))
		return PTR_ERR(vma);

	i915_gem_object_lock(ctx->obj, NULL);
	err = i915_gem_object_set_to_gtt_domain(ctx->obj, true);
	if (err)
		goto out_unlock;

	rq = intel_engine_create_kernel_request(ctx->engine);
	if (IS_ERR(rq)) {
		err = PTR_ERR(rq);
		goto out_unpin;
	}

	cs = intel_ring_begin(rq, 4);
	if (IS_ERR(cs)) {
		err = PTR_ERR(cs);
		goto out_rq;
	}

	if (GRAPHICS_VER(ctx->engine->i915) >= 8) {
		*cs++ = MI_STORE_DWORD_IMM_GEN4 | 1 << 22;
		*cs++ = lower_32_bits(i915_ggtt_offset(vma) + offset);
		*cs++ = upper_32_bits(i915_ggtt_offset(vma) + offset);
		*cs++ = v;
	} else if (GRAPHICS_VER(ctx->engine->i915) >= 4) {
		*cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT;
		*cs++ = 0;
		*cs++ = i915_ggtt_offset(vma) + offset;
		*cs++ = v;
	} else {
		*cs++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL;
		*cs++ = i915_ggtt_offset(vma) + offset;
		*cs++ = v;
		*cs++ = MI_NOOP;
	}
	intel_ring_advance(rq, cs);

	err = i915_request_await_object(rq, vma->obj, true);
	if (err == 0)
		err = i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE);

out_rq:
	i915_request_add(rq);
out_unpin:
	i915_vma_unpin(vma);
out_unlock:
	i915_gem_object_unlock(ctx->obj);

	return err;
}

static bool always_valid(struct context *ctx)
{
	return true;
}

static bool needs_fence_registers(struct context *ctx)
{
	struct intel_gt *gt = ctx->engine->gt;

	if (intel_gt_is_wedged(gt))
		return false;

	return gt->ggtt->num_fences;
}

static bool needs_mi_store_dword(struct context *ctx)
{
	if (intel_gt_is_wedged(ctx->engine->gt))
		return false;

	return intel_engine_can_store_dword(ctx->engine);
}

static const struct igt_coherency_mode {
	const char *name;
	int (*set)(struct context *ctx, unsigned long offset, u32 v);
	int (*get)(struct context *ctx, unsigned long offset, u32 *v);
	bool (*valid)(struct context *ctx);
} igt_coherency_mode[] = {
	{ "cpu", cpu_set, cpu_get, always_valid },
	{ "gtt", gtt_set, gtt_get, needs_fence_registers },
	{ "wc", wc_set, wc_get, always_valid },
	{ "gpu", gpu_set, NULL, needs_mi_store_dword },
	{ },
};

static struct intel_engine_cs *
random_engine(struct drm_i915_private *i915, struct rnd_state *prng)
{
	struct intel_engine_cs *engine;
	unsigned int count;

	count = 0;
	for_each_uabi_engine(engine, i915)
		count++;

	count = i915_prandom_u32_max_state(count, prng);
	for_each_uabi_engine(engine, i915)
		if (count-- == 0)
			return engine;

	return NULL;
}

static int igt_gem_coherency(void *arg)
{
	const unsigned int ncachelines = PAGE_SIZE/64;
	struct drm_i915_private *i915 = arg;
	const struct igt_coherency_mode *read, *write, *over;
	unsigned long count, n;
	u32 *offsets, *values;
	I915_RND_STATE(prng);
	struct context ctx;
	int err = 0;

	/*
	 * We repeatedly write, overwrite and read from a sequence of
	 * cachelines in order to try and detect incoherency (unflushed writes
	 * from either the CPU or GPU). Each setter/getter uses our cache
	 * domain API which should prevent incoherency.
	 */

	offsets = kmalloc_array(ncachelines, 2*sizeof(u32), GFP_KERNEL);
	if (!offsets)
		return -ENOMEM;
	for (count = 0; count < ncachelines; count++)
		offsets[count] = count * 64 + 4 * (count % 16);

	values = offsets + ncachelines;

	ctx.engine = random_engine(i915, &prng);
	if (!ctx.engine) {
		err = -ENODEV;
		goto out_free;
	}
	pr_info("%s: using %s\n", __func__, ctx.engine->name);
	intel_engine_pm_get(ctx.engine);

	for (over = igt_coherency_mode; over->name; over++) {
		if (!over->set)
			continue;

		if (!over->valid(&ctx))
			continue;

		for (write = igt_coherency_mode; write->name; write++) {
			if (!write->set)
				continue;

			if (!write->valid(&ctx))
				continue;

			for (read = igt_coherency_mode; read->name; read++) {
				if (!read->get)
					continue;

				if (!read->valid(&ctx))
					continue;

				for_each_prime_number_from(count, 1, ncachelines) {
					ctx.obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
					if (IS_ERR(ctx.obj)) {
						err = PTR_ERR(ctx.obj);
						goto out_pm;
					}

					i915_random_reorder(offsets, ncachelines, &prng);
					for (n = 0; n < count; n++)
						values[n] = prandom_u32_state(&prng);

					for (n = 0; n < count; n++) {
						err = over->set(&ctx, offsets[n], ~values[n]);
						if (err) {
							pr_err("Failed to set stale value[%ld/%ld] in object using %s, err=%d\n",
							       n, count, over->name, err);
							goto put_object;
						}
					}

					for (n = 0; n < count; n++) {
						err = write->set(&ctx, offsets[n], values[n]);
						if (err) {
							pr_err("Failed to set value[%ld/%ld] in object using %s, err=%d\n",
							       n, count, write->name, err);
							goto put_object;
						}
					}

					for (n = 0; n < count; n++) {
						u32 found;

						err = read->get(&ctx, offsets[n], &found);
						if (err) {
							pr_err("Failed to get value[%ld/%ld] in object using %s, err=%d\n",
							       n, count, read->name, err);
							goto put_object;
						}

						if (found != values[n]) {
							pr_err("Value[%ld/%ld] mismatch, (overwrite with %s) wrote [%s] %x read [%s] %x (inverse %x), at offset %x\n",
							       n, count, over->name,
							       write->name, values[n],
							       read->name, found,
							       ~values[n], offsets[n]);
							err = -EINVAL;
							goto put_object;
						}
					}

					i915_gem_object_put(ctx.obj);
				}
			}
		}
	}
out_pm:
	intel_engine_pm_put(ctx.engine);
out_free:
	kfree(offsets);
	return err;

put_object:
	i915_gem_object_put(ctx.obj);
	goto out_pm;
}

int i915_gem_coherency_live_selftests(struct drm_i915_private *i915)
{
	static const struct i915_subtest tests[] = {
		SUBTEST(igt_gem_coherency),
	};

	return i915_subtests(tests, i915);
}
