/*
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 * Authors:
 *    Imre Deak <imre.deak@intel.com>
 */
#include "config.h"

#include "igt.h"
#include <cairo.h>
#include <errno.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <math.h>
#include "intel_bufmgr.h"

#define MAX_CONNECTORS  10
#define MAX_CRTCS       6

/* max combinations with repetitions */
#define MAX_COMBINATION_ELEMS   MAX_CRTCS

static int drm_fd;
static drmModeRes *drm_resources;
static int filter_test_id;
static bool dry_run;

const drmModeModeInfo mode_640_480 = {
	.name		= "640x480",
	.vrefresh	= 60,
	.clock		= 25200,

	.hdisplay	= 640,
	.hsync_start	= 656,
	.hsync_end	= 752,
	.htotal		= 800,

	.vdisplay	= 480,
	.vsync_start	= 490,
	.vsync_end	= 492,
	.vtotal		= 525,

	.flags		= DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
};

enum test_flags {
	TEST_INVALID			= 0x01,
	TEST_CLONE			= 0x02,
	TEST_SINGLE_CRTC_CLONE		= 0x04,
	TEST_EXCLUSIVE_CRTC_CLONE	= 0x08,
	TEST_STEALING			= 0x10,
	TEST_TIMINGS			= 0x20,
};

struct test_config {
	const char *name;
	enum test_flags flags;
	drmModeRes *resources;
};

struct connector_config {
	drmModeConnector *connector;
	int crtc_idx;
	drmModeModeInfo default_mode;
};

struct crtc_config {
	int crtc_idx;
	int crtc_id;
	int pipe_id;
	int connector_count;
	struct connector_config *cconfs;
	struct igt_fb fb_info;
	drmModeModeInfo mode;
};

static bool drm_mode_equal(drmModeModeInfo *m1, drmModeModeInfo *m2)
{
#define COMP(x) do { if (m1->x != m2->x) return false; } while (0)
	COMP(vrefresh);
	COMP(clock);
	COMP(hdisplay);
	COMP(hsync_start);
	COMP(hsync_end);
	COMP(htotal);
	COMP(vdisplay);
	COMP(vsync_start);
	COMP(vsync_end);
	COMP(vtotal);
	COMP(flags);

	return true;
}

static bool connector_supports_mode(drmModeConnector *connector,
				    drmModeModeInfo *mode)
{
	int i;

	for (i = 0; i < connector->count_modes; i++)
		if (drm_mode_equal(&connector->modes[i], mode))
			return true;

	return false;
}

static bool crtc_supports_mode(struct crtc_config *crtc, drmModeModeInfo *mode)
{
	int i;

	for (i = 0; i < crtc->connector_count; i++) {
		if (!connector_supports_mode(crtc->cconfs[i].connector, mode))
			return false;
	}

	return true;
}

static int paint_fb(struct igt_fb *fb, const char *test_name,
		    const char **crtc_str, int crtc_count, int current_crtc_idx)
{
	double x, y;
	cairo_t *cr;
	int i;

	cr = igt_get_cairo_ctx(drm_fd, fb);

	cairo_move_to(cr, fb->width / 2, fb->height / 2);
	cairo_set_font_size(cr, 24);
	igt_cairo_printf_line(cr, align_hcenter, 40, "%s", test_name);

	cairo_get_current_point(cr, &x, &y);
	cairo_move_to(cr, 60, y);

	for (i = 0; i < crtc_count; i++) {
		if (i == current_crtc_idx) {
			cairo_get_current_point(cr, &x, &y);
			cairo_move_to(cr, x - 20, y);
			igt_cairo_printf_line(cr, align_right, 20, "X");
			cairo_move_to(cr, x, y);
		}
		igt_cairo_printf_line(cr, align_left, 20, "%s",
					  crtc_str[i]);
	}

	igt_put_cairo_ctx(drm_fd, fb, cr);

	return 0;
}

static void create_fb_for_crtc(struct crtc_config *crtc,
			       struct igt_fb *fb_info)
{
	int bpp;
	int depth;
	int fb_id;

	bpp = 32;
	depth = 24;
	fb_id = igt_create_pattern_fb(drm_fd, crtc->mode.hdisplay,
				      crtc->mode.vdisplay,
				      igt_bpp_depth_to_drm_format(bpp, depth),
				      LOCAL_DRM_FORMAT_MOD_NONE,
				      fb_info);
	igt_assert_lt(0, fb_id);
}

static void get_mode_for_crtc(struct crtc_config *crtc,
			      drmModeModeInfo *mode_ret)
{
	drmModeModeInfo mode;
	int i;

	/*
	 * First try to select a default mode that is supported by all
	 * connectors.
	 */
	for (i = 0; i < crtc->connector_count; i++) {
		mode = crtc->cconfs[i].default_mode;
		if (crtc_supports_mode(crtc, &mode))
			goto found;
	}

	/*
	 * Then just fall back to find any that is supported by all
	 * connectors.
	 */
	for (i = 0; i < crtc->cconfs[0].connector->count_modes; i++) {
		mode = crtc->cconfs[0].connector->modes[i];
		if (crtc_supports_mode(crtc, &mode))
			goto found;
	}

	/*
	 * If none is found then just pick the default mode of the first
	 * connector and hope the other connectors can support it by scaling
	 * etc.
	 */
	mode = crtc->cconfs[0].default_mode;
found:
	*mode_ret = mode;
}

static int get_encoder_idx(drmModeRes *resources, drmModeEncoder *encoder)
{
	int i;

	for (i = 0; i < resources->count_encoders; i++)
		if (resources->encoders[i] == encoder->encoder_id)
			return i;
	igt_assert(0);
}

static void get_crtc_config_str(struct crtc_config *crtc, char *buf,
				size_t buf_size)
{
	int pos;
	int i;

	pos = snprintf(buf, buf_size,
		       "CRTC[%d] [Pipe %s] Mode: %s@%dHz Connectors: ",
		       crtc->crtc_id, kmstest_pipe_name(crtc->pipe_id),
		       crtc->mode.name, crtc->mode.vrefresh);
	if (pos > buf_size)
		return;
	for (i = 0; i < crtc->connector_count; i++) {
		drmModeConnector *connector = crtc->cconfs[i].connector;

		pos += snprintf(&buf[pos], buf_size - pos,
			"%s%s-%d[%d]", i ? ", " : "",
			kmstest_connector_type_str(connector->connector_type),
			connector->connector_type_id, connector->connector_id);
		if (pos > buf_size)
			return;
	}
}

static void setup_crtcs(drmModeRes *resources, struct connector_config *cconf,
			int connector_count, struct crtc_config *crtcs,
			int *crtc_count_ret, bool *config_valid_ret)
{
	struct crtc_config *crtc;
	int crtc_count;
	bool config_valid;
	int i;
	int encoder_usage_count[resources->count_encoders];

	kmstest_unset_all_crtcs(drm_fd, resources);

	i = 0;
	crtc_count = 0;
	crtc = crtcs;
	config_valid = true;

	while (i < connector_count) {
		drmModeCrtc *drm_crtc;
		unsigned long encoder_mask;
		int j;

		igt_assert_lt(crtc_count, MAX_CRTCS);

		crtc->crtc_idx = cconf[i].crtc_idx;
		drm_crtc = drmModeGetCrtc(drm_fd,
					  resources->crtcs[crtc->crtc_idx]);
		crtc->crtc_id = drm_crtc->crtc_id;
		drmModeFreeCrtc(drm_crtc);
		crtc->pipe_id = kmstest_get_pipe_from_crtc_id(drm_fd,
							      crtc->crtc_id);

		crtc->connector_count = 1;
		for (j = i + 1; j < connector_count; j++)
			if (cconf[j].crtc_idx == crtc->crtc_idx)
				crtc->connector_count++;

		crtc->cconfs = malloc(sizeof(*crtc->cconfs) *
				      crtc->connector_count);
		igt_assert(crtc->cconfs);

		encoder_mask = 0;
		for (j = 0; j < crtc->connector_count; j++) {
			drmModeConnector *connector;
			drmModeEncoder *encoder;

			crtc->cconfs[j] = cconf[i + j];
			connector = cconf[i + j].connector;

			/* Intel connectors have only a single encoder */
			if (connector->count_encoders == 1) {
				encoder = drmModeGetEncoder(drm_fd,
							    connector->encoders[0]);
			} else {
				igt_assert_eq(connector->connector_type,
					      DRM_MODE_CONNECTOR_DisplayPort);

				igt_assert(connector->count_encoders >= crtc->crtc_idx);
				encoder = drmModeGetEncoder(drm_fd,
					connector->encoders[crtc_count]);
			}
			igt_assert(encoder);

			config_valid &= !!(encoder->possible_crtcs &
					  (1 << crtc->crtc_idx));

			encoder_mask |= 1 << get_encoder_idx(resources,
							     encoder);
			config_valid &= !(encoder_mask &
					  ~encoder->possible_clones);

			drmModeFreeEncoder(encoder);
		}
		get_mode_for_crtc(crtc, &crtc->mode);
		create_fb_for_crtc(crtc, &crtc->fb_info);

		i += crtc->connector_count;
		crtc_count++;
		crtc++;
	}

	memset(encoder_usage_count, 0, sizeof(encoder_usage_count));
	for (i = 0; i < connector_count; i++) {
		drmModeConnector *connector = cconf[i].connector;
		drmModeEncoder *encoder;
		int idx = 0;

		/* DP MST configs are presumed valid */
		if (connector->count_encoders > 1)
			idx = cconf[i].crtc_idx;

		encoder = drmModeGetEncoder(drm_fd, connector->encoders[idx]);
		encoder_usage_count[get_encoder_idx(resources, encoder)]++;
		drmModeFreeEncoder(encoder);
	}
	for (i = 0; i < resources->count_encoders; i++)
		if (encoder_usage_count[i] > 1)
			config_valid = false;

	*crtc_count_ret = crtc_count;
	*config_valid_ret = config_valid;
}

static void cleanup_crtcs(struct crtc_config *crtcs, int crtc_count)
{
	int i;

	for (i = 0; i < crtc_count; i++) {
		igt_remove_fb(drm_fd, &crtcs[i].fb_info);
		drmModeSetCrtc(drm_fd, crtcs[i].crtc_id, 0, 0, 0, NULL, 0, NULL);

		free(crtcs[i].cconfs);
	}
}

static uint32_t *get_connector_ids(struct crtc_config *crtc)
{
	uint32_t *ids;
	int i;

	ids = malloc(sizeof(*ids) * crtc->connector_count);
	igt_assert(ids);
	for (i = 0; i < crtc->connector_count; i++)
		ids[i] = crtc->cconfs[i].connector->connector_id;

	return ids;
}

static int test_stealing(int fd, struct crtc_config *crtc, uint32_t *ids)
{
	int i, ret = 0;

	if (!crtc->connector_count)
		return drmModeSetCrtc(fd, crtc->crtc_id,
				     crtc->fb_info.fb_id, 0, 0,
				     ids, crtc->connector_count, &crtc->mode);

	for (i = 0; i < crtc->connector_count; ++i) {
		ret = drmModeSetCrtc(fd, crtc->crtc_id,
				     crtc->fb_info.fb_id, 0, 0,
				     &ids[i], 1, &crtc->mode);

		igt_assert_eq(ret, 0);

		ret = drmModeSetCrtc(fd, crtc->crtc_id,
				     crtc->fb_info.fb_id, 0, 0,
				     ids, crtc->connector_count, &crtc->mode);

		/* This should fail with -EINVAL */
		if (!ret)
			return 0;
	}

	return ret;
}

static double frame_time(const drmModeModeInfo *kmode)
{
	return 1000.0 * kmode->htotal * kmode->vtotal / kmode->clock;
}

static double line_time(const drmModeModeInfo *kmode)
{
	return 1000.0 * kmode->htotal / kmode->clock;
}

static void check_timings(int crtc_idx, const drmModeModeInfo *kmode)
{
#define CALIBRATE_TS_STEPS 120 /* ~2s has to be less than 128! */
	drmVBlank wait;
	igt_stats_t stats;
	uint32_t last_seq;
	uint64_t last_timestamp;
	double expected;
	double accuracy;
	double mean;
	double stddev;
	int n;

	memset(&wait, 0, sizeof(wait));
	wait.request.type = kmstest_get_vbl_flag(crtc_idx);
	wait.request.type |= DRM_VBLANK_RELATIVE | DRM_VBLANK_NEXTONMISS;
	do_or_die(drmWaitVBlank(drm_fd, &wait));

	last_seq = wait.reply.sequence;
	last_timestamp = wait.reply.tval_sec;
	last_timestamp *= 1000000;
	last_timestamp += wait.reply.tval_usec;

	memset(&wait, 0, sizeof(wait));
	wait.request.type = kmstest_get_vbl_flag(crtc_idx);
	wait.request.type |= DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
	wait.request.sequence = last_seq;
	for (n = 0; n < CALIBRATE_TS_STEPS; n++) {
		drmVBlank check = {};

		++wait.request.sequence;
		do_or_die(drmWaitVBlank(drm_fd, &wait));

		/* Double check that haven't already missed the vblank */
		check.request.type = kmstest_get_vbl_flag(crtc_idx);
		check.request.type |= DRM_VBLANK_RELATIVE;
		do_or_die(drmWaitVBlank(drm_fd, &check));

		igt_assert(!igt_vblank_after(check.reply.sequence, wait.request.sequence));
	}

	igt_stats_init_with_size(&stats, CALIBRATE_TS_STEPS);
	for (n = 0; n < CALIBRATE_TS_STEPS; n++) {
		struct drm_event_vblank ev;
		uint64_t now;

		igt_assert(read(drm_fd, &ev, sizeof(ev)) == sizeof(ev));
		igt_assert_eq(ev.sequence, last_seq + 1);

		now = ev.tv_sec;
		now *= 1000000;
		now += ev.tv_usec;

		igt_stats_push(&stats, now - last_timestamp);

		last_timestamp = now;
		last_seq = ev.sequence;
	}

	expected = frame_time(kmode);

	mean = igt_stats_get_mean(&stats);
	stddev = igt_stats_get_std_deviation(&stats);

	/* 99.7% samples fall within `accuracy` on both sides of mean in normal
	 * distribution if `accuracy = 3 * sigma`.
	 * https://en.wikipedia.org/wiki/68%E2%80%9395%E2%80%9399.7_rule
	 *
	 * The value of 99.7% was chosen to suit requirements of test cases
	 * which depend on timing, giving the lowest acceptable MTBF of 5.6s
	 * for 60Hz sampling rate.
	 */
	accuracy = 3. * stddev;

	igt_info("Expected frametime: %.0fus; measured %.1fus +- %.3fus accuracy %.2f%% [%.2f scanlines]\n",
		 expected, mean, stddev,
		 100 * accuracy / mean, accuracy / line_time(kmode));

	/* 99.7% samples within one scanline on each side of mean */
	igt_assert_f(accuracy < line_time(kmode),
		     "vblank accuracy (%.3fus, %.1f%%) worse than a scanline (%.3fus)\n",
		     accuracy, 100 * accuracy / mean, line_time(kmode));

	/* At least 90% of frame times fall within the one scanline on each
	 * side of expected mean.
	 *
	 * Expected scanline duration:
	 * 	(expected - accuracy, expected + accuracy).
	 * Assuming maximum difference allowed:
	 * 	expected = mean + n * sigma
	 * the scanline duration becomes:
	 * 	(mean - accuracy + n * sigma, mean + accuracy + n * sigma)
	 * The expected scanline captures the following number of samples
	 * from each side of expected:
	 * 	(erf(abs(-(accuracy/sigma) + n) / sqrt(2))
	 * 	+ erf((accuracy/sigma) + n) / sqrt(2))) / 2
	 * 	= samples
	 *
	 * Solving for samples = 0.9:
	 * 	n = 1.718
	 *
	 * See:
	 * https://en.wikipedia.org/wiki/Standard_deviation#Rules_for_normally_distributed_data
	 */
	igt_assert_f(fabs(mean - expected) < 1.718 * stddev,
		     "vblank interval differs from modeline! expected %.1fus, measured %1.fus +- %.3fus, difference %.1fus (%.1f sigma)\n",
		     expected, mean, stddev,
		     fabs(mean - expected), fabs(mean - expected) / stddev);
}

static void test_crtc_config(const struct test_config *tconf,
			     struct crtc_config *crtcs, int crtc_count)
{
	char str_buf[MAX_CRTCS][1024];
	const char *crtc_strs[MAX_CRTCS];
	struct crtc_config *crtc;
	static int test_id;
	bool config_failed = false;
	int ret = 0;
	int i;

	test_id++;

	if (filter_test_id && filter_test_id != test_id)
		return;

	igt_info("  Test id#%d CRTC count %d\n", test_id, crtc_count);

	for (i = 0; i < crtc_count; i++) {
		get_crtc_config_str(&crtcs[i], str_buf[i], sizeof(str_buf[i]));
		crtc_strs[i] = &str_buf[i][0];
	}

	if (dry_run) {
		for (i = 0; i < crtc_count; i++)
			igt_info("    %s\n", crtc_strs[i]);
		return;
	}

	for (i = 0; i < crtc_count; i++) {
		uint32_t *ids;

		crtc = &crtcs[i];

		igt_info("    %s\n", crtc_strs[i]);

		create_fb_for_crtc(crtc, &crtc->fb_info);
		paint_fb(&crtc->fb_info, tconf->name, crtc_strs, crtc_count, i);

		ids = get_connector_ids(crtc);
		if (tconf->flags & TEST_STEALING)
			ret = test_stealing(drm_fd, crtc, ids);
		else
			ret = drmModeSetCrtc(drm_fd, crtc->crtc_id,
					     crtc->fb_info.fb_id, 0, 0, ids,
					     crtc->connector_count, &crtc->mode);

		free(ids);

		if (ret < 0) {
			igt_assert_eq(errno, EINVAL);
			config_failed = true;
		}
	}

	igt_assert(config_failed == !!(tconf->flags & TEST_INVALID));

	if (ret == 0 && tconf->flags & TEST_TIMINGS)
		check_timings(crtcs[0].crtc_idx, &crtcs[0].mode);

	return;
}

static void test_one_combination(const struct test_config *tconf,
				 struct connector_config *cconfs,
				 int connector_count)
{
	struct crtc_config crtcs[MAX_CRTCS];
	int crtc_count;
	bool config_valid;

	setup_crtcs(tconf->resources, cconfs, connector_count, crtcs,
		    &crtc_count, &config_valid);

	if (config_valid == !(tconf->flags & TEST_INVALID))
		test_crtc_config(tconf, crtcs, crtc_count);

	cleanup_crtcs(crtcs, crtc_count);
}

static int assign_crtc_to_connectors(const struct test_config *tconf,
				     int *crtc_idxs, int connector_count,
				     struct connector_config *cconfs)
{
	unsigned long crtc_idx_mask;
	int i;

	crtc_idx_mask = 0;
	for (i = 0; i < connector_count; i++) {
		int crtc_idx = crtc_idxs[i];

		if ((tconf->flags & TEST_SINGLE_CRTC_CLONE) &&
		    crtc_idx_mask & ~(1 << crtc_idx))
			return -1;

		if ((tconf->flags & TEST_EXCLUSIVE_CRTC_CLONE) &&
		    crtc_idx_mask & (1 << crtc_idx))
			return -1;

		crtc_idx_mask |= 1 << crtc_idx;

		cconfs[i].crtc_idx = crtc_idx;
	}

	return 0;
}

static int get_one_connector(drmModeRes *resources, int connector_id,
			     struct connector_config *cconf)
{
	drmModeConnector *connector;

	connector = drmModeGetConnectorCurrent(drm_fd, connector_id);
	igt_assert(connector);
	cconf->connector = connector;

	if (connector->connection != DRM_MODE_CONNECTED) {
		drmModeFreeConnector(connector);
		return -1;
	}

	if (!kmstest_get_connector_default_mode(drm_fd, connector,
						&cconf->default_mode)) {
		drmModeFreeConnector(connector);
		return -1;
	}

	return 0;
}

static int get_connectors(drmModeRes *resources, int *connector_idxs,
			  int connector_count, struct connector_config *cconfs)
{
	int i;

	for (i = 0; i < connector_count; i++) {
		int connector_idx;
		int connector_id;

		connector_idx = connector_idxs[i];
		igt_assert_lt(connector_idx, resources->count_connectors);
		connector_id = resources->connectors[connector_idx];

		if (get_one_connector(resources, connector_id, &cconfs[i]) < 0)
			goto err;

	}

	return 0;

err:
	while (i--)
		drmModeFreeConnector(cconfs[i].connector);

	return -1;
}

static void free_connectors(struct connector_config *cconfs,
			    int connector_count)
{
	int i;

	for (i = 0; i < connector_count; i++)
		drmModeFreeConnector(cconfs[i].connector);
}

struct combination {
	int elems[MAX_COMBINATION_ELEMS];
};

struct combination_set {
	int count;
	int capacity;
	struct combination *items;
};

/*
 * Get all possible selection of k elements from n elements with or without
 * repetitions.
 */
static void iterate_combinations(int n, int k, bool allow_repetitions,
				 int depth, int base, struct combination *comb,
				 struct combination_set *set)
{
	int v;

	if (!k) {
		igt_assert(set->count < set->capacity);
		set->items[set->count++] = *comb;
		return;
	}

	for (v = base; v < n; v++) {
		comb->elems[depth] = v;
		iterate_combinations(n, k - 1, allow_repetitions,
				     depth + 1, allow_repetitions ? 0 : v + 1,
				     comb, set);
	}

}

static void get_combinations(int n, int k, bool allow_repetitions,
			     struct combination_set *set)
{
	struct combination comb;

	igt_assert(k <= ARRAY_SIZE(set->items[0].elems));
	set->count = 0;
	iterate_combinations(n, k, allow_repetitions, 0, 0, &comb, set);
}

static void test_combinations(const struct test_config *tconf,
			      int connector_count)
{
	struct combination_set connector_combs;
	struct combination_set crtc_combs;
	struct connector_config *cconfs;
	int i;

	if (connector_count > 2 && (tconf->flags & TEST_STEALING))
		return;

	igt_assert(tconf->resources);

	connector_combs.capacity = pow(tconf->resources->count_connectors,
				       tconf->resources->count_crtcs + 1);
	crtc_combs.capacity = pow(tconf->resources->count_crtcs,
				  tconf->resources->count_crtcs + 1);

	connector_combs.items = malloc(connector_combs.capacity * sizeof(struct combination));
	crtc_combs.items = malloc(crtc_combs.capacity * sizeof(struct combination));

	get_combinations(tconf->resources->count_connectors, connector_count,
			 false, &connector_combs);
	get_combinations(tconf->resources->count_crtcs, connector_count,
			 true, &crtc_combs);

	igt_info("Testing: %s %d connector combinations\n", tconf->name,
		 connector_count);
	for (i = 0; i < connector_combs.count; i++) {
		int *connector_idxs;
		int ret;
		int j;

		cconfs = malloc(sizeof(*cconfs) * connector_count);
		igt_assert(cconfs);

		connector_idxs = &connector_combs.items[i].elems[0];
		ret = get_connectors(tconf->resources, connector_idxs,
				     connector_count, cconfs);
		if (ret < 0)
			goto free_cconfs;

		for (j = 0; j < crtc_combs.count; j++) {
			int *crtc_idxs = &crtc_combs.items[j].elems[0];
			ret = assign_crtc_to_connectors(tconf, crtc_idxs,
							connector_count,
						        cconfs);
			if (ret < 0)
				continue;

			test_one_combination(tconf, cconfs, connector_count);
		}

		free_connectors(cconfs, connector_count);
free_cconfs:
		free(cconfs);
	}

	free(connector_combs.items);
	free(crtc_combs.items);
}

static void run_test(const struct test_config *tconf)
{
	int connector_num;

	connector_num = tconf->flags & TEST_CLONE ? 2 : 1;
	for (; connector_num <= tconf->resources->count_crtcs; connector_num++)
		test_combinations(tconf, connector_num);
}

static int opt_handler(int opt, int opt_index, void *data)
{
	switch (opt) {
	case 'd':
		dry_run = true;
		break;
	case 't':
		filter_test_id = atoi(optarg);
		break;
	default:
		igt_assert(0);
	}

	return 0;
}

int main(int argc, char **argv)
{
	const struct {
		enum test_flags flags;
		const char *name;
	} tests[] = {
		{ TEST_TIMINGS, "basic" },
		{ TEST_CLONE | TEST_SINGLE_CRTC_CLONE,
					"basic-clone-single-crtc" },
		{ TEST_INVALID | TEST_CLONE | TEST_SINGLE_CRTC_CLONE,
					"invalid-clone-single-crtc" },
		{ TEST_INVALID | TEST_CLONE | TEST_EXCLUSIVE_CRTC_CLONE,
					"invalid-clone-exclusive-crtc" },
		{ TEST_CLONE | TEST_EXCLUSIVE_CRTC_CLONE,
					"clone-exclusive-crtc" },
		{ TEST_INVALID | TEST_CLONE | TEST_SINGLE_CRTC_CLONE | TEST_STEALING,
					"invalid-clone-single-crtc-stealing" }
	};
	const char *help_str =
	       "  -d\t\tDon't run any test, only print what would be done. (still needs DRM access)\n"
	       "  -t <test id>\tRun only the test with this id.";
	int i;
	int ret;

	ret = igt_subtest_init_parse_opts(&argc, argv, "dt:", NULL, help_str,
					  opt_handler, NULL);
	if (ret < 0)
		return ret == -1 ? 0 : ret;

	igt_skip_on_simulation();

	igt_assert_f(!(dry_run && filter_test_id),
		     "only one of -d and -t is accepted\n");

	igt_fixture {
		drm_fd = drm_open_driver_master(DRIVER_ANY);
		if (!dry_run)
			kmstest_set_vt_graphics_mode();

		drm_resources = drmModeGetResources(drm_fd);
		igt_require(drm_resources);
	}

	for (i = 0; i < ARRAY_SIZE(tests); i++) {
		igt_subtest(tests[i].name) {
			struct test_config tconf = {
				.flags		= tests[i].flags,
				.name		= tests[i].name,
				.resources	= drm_resources,
			};
			run_test(&tconf);
		}
	}

	igt_fixture {
		drmModeFreeResources(drm_resources);

		close(drm_fd);
	}

	igt_exit();
}
