diff mbox

[i-g-t,1/4] lib: add function to change connector states

Message ID 1403099053-31243-2-git-send-email-thomas.wood@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Thomas Wood June 18, 2014, 1:44 p.m. UTC
Add an API function and a test program to force a particular state on a
connector.

Signed-off-by: Thomas Wood <thomas.wood@intel.com>
---
 lib/igt_kms.c               | 57 +++++++++++++++++++++++++++++
 lib/igt_kms.h               | 16 ++++++++
 tests/Makefile.sources      |  1 +
 tests/kms_force_connector.c | 89 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 163 insertions(+)
 create mode 100644 tests/kms_force_connector.c

Comments

Chris Wilson June 18, 2014, 2:05 p.m. UTC | #1
On Wed, Jun 18, 2014 at 02:44:10PM +0100, Thomas Wood wrote:
> +static int get_card_number(int fd)
> +{
> +	struct stat buf;
> +
> +	/* find the minor number of the device */
> +	fstat(fd, &buf);
> +
> +	return minor(buf.st_rdev);

This mixes in rendernode/controlnode tags.
-Chris
diff mbox

Patch

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index c0f4f6c..8de8e0a 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -384,6 +384,63 @@  err1:
 	return -1;
 }
 
+static int get_card_number(int fd)
+{
+	struct stat buf;
+
+	/* find the minor number of the device */
+	fstat(fd, &buf);
+
+	return minor(buf.st_rdev);
+}
+
+/**
+ * kmstest_force_connector:
+ * @fd: drm file descriptor
+ * @connector: connector
+ * @state: state to force on @connector
+ *
+ * Force the specified state on the specified connector.
+ */
+void kmstest_force_connector(int drm_fd, drmModeConnector *connector, enum
+			     kmstest_force_connector_state state)
+{
+	char *path;
+	const char *value;
+	int debugfs_fd, ret;
+
+	switch (state) {
+	case FORCE_CONNECTOR_ON:
+		value = "on";
+		break;
+	case FORCE_CONNECTOR_DIGITAL:
+		value = "digital";
+		break;
+	case FORCE_CONNECTOR_OFF:
+		value = "off";
+		break;
+
+	default:
+	case FORCE_CONNECTOR_UNSPECIFIED:
+		value = "unspecified";
+		break;
+	}
+
+	asprintf(&path, "/sys/kernel/debug/dri/%d/%s-%d/force",
+		 get_card_number(drm_fd),
+		 kmstest_connector_type_str(connector->connector_type),
+		 connector->connector_type_id);
+	debugfs_fd = open(path, O_WRONLY | O_TRUNC);
+	free(path);
+
+	igt_assert(debugfs_fd != -1);
+
+	ret = write(debugfs_fd, value, strlen(value));
+	close(debugfs_fd);
+
+	igt_assert(ret != -1);
+}
+
 void kmstest_free_connector_config(struct kmstest_connector_config *config)
 {
 	drmModeFreeCrtc(config->crtc);
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 7d015b4..45a98c8 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -76,11 +76,27 @@  struct kmstest_connector_config {
 	int pipe;
 };
 
+/**
+ * kmstest_force_connector_state:
+ * @FORCE_CONNECTOR_UNSPECIFIED: Unspecified
+ * @FORCE_CONNECTOR_ON: On
+ * @FORCE_CONNECTOR_DIGITAL: Digital
+ * @FORCE_CONNECTOR_OFF: Off
+ */
+enum kmstest_force_connector_state {
+	FORCE_CONNECTOR_UNSPECIFIED,
+	FORCE_CONNECTOR_ON,
+	FORCE_CONNECTOR_DIGITAL,
+	FORCE_CONNECTOR_OFF
+};
+
 int kmstest_get_connector_default_mode(int drm_fd, drmModeConnector *connector,
 				      drmModeModeInfo *mode);
 int kmstest_get_connector_config(int drm_fd, uint32_t connector_id,
 				 unsigned long crtc_idx_mask,
 				 struct kmstest_connector_config *config);
+void kmstest_force_connector(int fd, drmModeConnector *connector,
+			     enum kmstest_force_connector_state state);
 void kmstest_free_connector_config(struct kmstest_connector_config *config);
 
 void kmstest_dump_mode(drmModeModeInfo *mode);
diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 17c0ab9..dc08a3c 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -138,6 +138,7 @@  TESTS_progs = \
 	gen3_render_tiledx_blits \
 	gen3_render_tiledy_blits \
 	gen7_forcewake_mt \
+	kms_force_connector \
 	kms_sink_crc_basic \
 	kms_fence_pin_leak \
 	pm_psr \
diff --git a/tests/kms_force_connector.c b/tests/kms_force_connector.c
new file mode 100644
index 0000000..0591da0
--- /dev/null
+++ b/tests/kms_force_connector.c
@@ -0,0 +1,89 @@ 
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ */
+
+#include "igt_core.h"
+#include "igt_kms.h"
+#include "drmtest.h"
+
+int
+main (int argc, char **argv)
+{
+	/* force the VGA output and test that it worked */
+	int drm_fd;
+	drmModeRes *res;
+	drmModeConnector *connector, *temp;
+	igt_display_t display;
+
+	igt_simple_init();
+
+	drm_fd = drm_open_any();
+	res = drmModeGetResources(drm_fd);
+
+	/* find the vga connector */
+	for (int i = 0; i < res->count_connectors; i++) {
+
+		connector = drmModeGetConnector(drm_fd, res->connectors[i]);
+
+		if (connector->connector_type == DRM_MODE_CONNECTOR_VGA)
+			break;
+
+		drmModeFreeConnector(connector);
+
+		connector = NULL;
+	}
+
+	igt_assert(connector);
+
+	/* force the connector on and check the reported values */
+	kmstest_force_connector(drm_fd, connector, FORCE_CONNECTOR_ON);
+	temp = drmModeGetConnector(drm_fd, connector->connector_id);
+	igt_assert(temp->connection == DRM_MODE_CONNECTED);
+	igt_assert(temp->count_modes > 0);
+	drmModeFreeConnector(temp);
+
+	/* attempt to use the display */
+	igt_set_vt_graphics_mode();
+
+	igt_display_init(&display, drm_fd);
+	igt_display_commit(&display);
+
+
+	/* force the connector off */
+	kmstest_force_connector(drm_fd, connector, FORCE_CONNECTOR_OFF);
+	temp = drmModeGetConnector(drm_fd, connector->connector_id);
+	igt_assert(temp->connection == DRM_MODE_DISCONNECTED);
+	igt_assert(temp->count_modes == 0);
+	drmModeFreeConnector(temp);
+
+
+	/* check that the previous state is restored */
+	kmstest_force_connector(drm_fd, connector, FORCE_CONNECTOR_UNSPECIFIED);
+	temp = drmModeGetConnector(drm_fd, connector->connector_id);
+	igt_assert(temp->connection == connector->connection);
+	drmModeFreeConnector(temp);
+
+	drmModeFreeConnector(connector);
+
+	igt_success();
+}