summaryrefslogtreecommitdiff
path: root/tests/kms_chamelium.c
diff options
context:
space:
mode:
authorArkadiusz Hiler <arkadiusz.hiler@intel.com>2020-04-14 11:14:47 +0300
committerArkadiusz Hiler <arkadiusz.hiler@intel.com>2020-04-15 12:35:55 +0300
commit04a8ae8a0a7e5d7818184c880181d289f7dc7c8f (patch)
treec8c54bddafcb6601c6cb330e74151c83e3875ebf /tests/kms_chamelium.c
parent150f5bba876690626641558540c1da72db018983 (diff)
tests/kms_chamelium: Test HPD for different mode handling scenarios
The default scenario is now performing all hotplugs with modes disabled on all connectors. This is the quickest of the tests and represents userspace not caring about the new display (e.g. explicitly disabled). *-hpd-enable-disable-mode covers the most common userspace behavior where each hotplug event is accompanied by a corresponding enabling / disabling commit. *-hpd-with-enabled-mode explicitly targets the scenario where we have mode enabled and never disable it as we do hotplugs to reproduce the issue we see with TypeC connectors for ICL and TGL. v2: - refresh igt_display output state after reprobing - get mode and set pipe only after we have connector plugged in v3: fix VGA subtest names (Kunal) Cc: Kunal Joshi <kunal1.joshi@intel.com> Cc: Imre Deak <imre.deak@intel.com> Issue: https://gitlab.freedesktop.org/drm/intel/issues/323 Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com> Reviewed-by: Kunal Joshi <kunal1.joshi@intel.com>
Diffstat (limited to 'tests/kms_chamelium.c')
-rw-r--r--tests/kms_chamelium.c315
1 files changed, 214 insertions, 101 deletions
diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
index 63ae077d..8b20bbbc 100644
--- a/tests/kms_chamelium.c
+++ b/tests/kms_chamelium.c
@@ -45,6 +45,12 @@ enum test_edid {
};
#define TEST_EDID_COUNT 5
+enum test_modeset_mode {
+ TEST_MODESET_ON,
+ TEST_MODESET_ON_OFF,
+ TEST_MODESET_OFF,
+};
+
typedef struct {
struct chamelium *chamelium;
struct chamelium_port **ports;
@@ -111,12 +117,17 @@ reprobe_connector(data_t *data, struct chamelium_port *port)
{
drmModeConnector *connector;
drmModeConnection status;
+ igt_output_t *output;
igt_debug("Reprobing %s...\n", chamelium_port_get_name(port));
connector = chamelium_port_get_connector(data->chamelium, port, true);
igt_assert(connector);
status = connector->connection;
+ /* let's make sure that igt_display is up to date too */
+ output = igt_output_from_connector(&data->display, connector);
+ igt_output_refresh(output);
+
drmModeFreeConnector(connector);
return status;
}
@@ -294,14 +305,140 @@ reset_state(data_t *data, struct chamelium_port *port)
}
}
+static void chamelium_paint_xr24_pattern(uint32_t *data,
+ size_t width, size_t height,
+ size_t stride, size_t block_size)
+{
+ uint32_t colors[] = { 0xff000000,
+ 0xffff0000,
+ 0xff00ff00,
+ 0xff0000ff,
+ 0xffffffff };
+ unsigned i, j;
+
+ for (i = 0; i < height; i++)
+ for (j = 0; j < width; j++)
+ *(data + i * stride / 4 + j) = colors[((j / block_size) + (i / block_size)) % 5];
+}
+
+static int chamelium_get_pattern_fb(data_t *data, size_t width, size_t height,
+ uint32_t fourcc, size_t block_size,
+ struct igt_fb *fb)
+{
+ int fb_id;
+ void *ptr;
+
+ igt_assert(fourcc == DRM_FORMAT_XRGB8888);
+
+ fb_id = igt_create_fb(data->drm_fd, width, height, fourcc,
+ LOCAL_DRM_FORMAT_MOD_NONE, fb);
+ igt_assert(fb_id > 0);
+
+ ptr = igt_fb_map_buffer(fb->fd, fb);
+ igt_assert(ptr);
+
+ chamelium_paint_xr24_pattern(ptr, width, height, fb->strides[0],
+ block_size);
+ igt_fb_unmap_buffer(fb, ptr);
+
+ return fb_id;
+}
+
+static void
+enable_output(data_t *data,
+ struct chamelium_port *port,
+ igt_output_t *output,
+ drmModeModeInfo *mode,
+ struct igt_fb *fb)
+{
+ igt_display_t *display = output->display;
+ igt_plane_t *primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
+ drmModeConnector *connector = chamelium_port_get_connector(
+ data->chamelium, port, false);
+
+ igt_assert(primary);
+
+ igt_plane_set_size(primary, mode->hdisplay, mode->vdisplay);
+ igt_plane_set_fb(primary, fb);
+ igt_output_override_mode(output, mode);
+
+ /* Clear any color correction values that might be enabled */
+ if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_DEGAMMA_LUT))
+ igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_DEGAMMA_LUT, NULL, 0);
+ if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_LUT))
+ igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_GAMMA_LUT, NULL, 0);
+ if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_CTM))
+ igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_CTM, NULL, 0);
+
+ igt_display_commit2(display, COMMIT_ATOMIC);
+
+ if (chamelium_port_get_type(port) == DRM_MODE_CONNECTOR_VGA)
+ usleep(250000);
+
+ drmModeFreeConnector(connector);
+}
+
+static enum pipe get_pipe_for_output(igt_display_t *display, igt_output_t *output)
+{
+ enum pipe pipe;
+
+ for_each_pipe(display, pipe) {
+ if (igt_pipe_connector_valid(pipe, output)) {
+ return pipe;
+ }
+ }
+
+ igt_assert_f(false, "No pipe found for output %s\n",
+ igt_output_name(output));
+}
+
+static void create_fb_for_mode(data_t *data, struct igt_fb *fb, drmModeModeInfo *mode)
+{
+ int fb_id;
+
+ fb_id = chamelium_get_pattern_fb(data, mode->hdisplay, mode->vdisplay,
+ DRM_FORMAT_XRGB8888, 64, fb);
+
+ igt_assert(fb_id > 0);
+}
+
+static drmModeModeInfo get_mode_for_port(struct chamelium *chamelium,
+ struct chamelium_port *port)
+{
+ drmModeConnector *connector = chamelium_port_get_connector(chamelium,
+ port, false);
+ drmModeModeInfo mode;
+ igt_assert(&connector->modes[0] != NULL);
+ memcpy(&mode, &connector->modes[0], sizeof(mode));
+ drmModeFreeConnector(connector);
+ return mode;
+}
+
+static igt_output_t *get_output_for_port(data_t *data,
+ struct chamelium_port *port)
+{
+ drmModeConnector *connector = chamelium_port_get_connector(data->chamelium,
+ port, false);
+ igt_output_t *output = igt_output_from_connector(&data->display,
+ connector);
+ drmModeFreeConnector(connector);
+ igt_assert(output != NULL);
+ return output;
+}
+
static const char test_basic_hotplug_desc[] =
"Check that we get uevents and updated connector status on "
"hotplug and unplug";
static void
-test_basic_hotplug(data_t *data, struct chamelium_port *port, int toggle_count)
+test_hotplug(data_t *data, struct chamelium_port *port, int toggle_count,
+ enum test_modeset_mode modeset_mode)
{
- struct udev_monitor *mon = igt_watch_hotplug();
int i;
+ enum pipe pipe;
+ struct igt_fb fb = {0};
+ drmModeModeInfo mode;
+ struct udev_monitor *mon = igt_watch_hotplug();
+ igt_output_t *output = get_output_for_port(data, port);
reset_state(data, NULL);
igt_hpd_storm_set_threshold(data->drm_fd, 0);
@@ -316,15 +453,36 @@ test_basic_hotplug(data_t *data, struct chamelium_port *port, int toggle_count)
DRM_MODE_CONNECTED);
igt_flush_hotplugs(mon);
+ if (modeset_mode == TEST_MODESET_ON_OFF ||
+ (modeset_mode == TEST_MODESET_ON && i == 0 )) {
+ if (i == 0) {
+ /* We can only get mode and pipe once we are connected */
+ pipe = get_pipe_for_output(&data->display, output);
+ mode = get_mode_for_port(data->chamelium, port);
+ create_fb_for_mode(data, &fb, &mode);
+ }
+
+ igt_output_set_pipe(output, pipe);
+ enable_output(data, port, output, &mode, &fb);
+ }
+
/* Now check if we get a hotplug from disconnection */
chamelium_unplug(data->chamelium, port);
wait_for_connector_after_hotplug(data, mon, port,
DRM_MODE_DISCONNECTED);
+
+ igt_flush_hotplugs(mon);
+
+ if (modeset_mode == TEST_MODESET_ON_OFF) {
+ igt_output_set_pipe(output, PIPE_NONE);
+ igt_display_commit2(&data->display, COMMIT_ATOMIC);
+ }
}
igt_cleanup_hotplug(mon);
igt_hpd_storm_reset(data->drm_fd);
+ igt_remove_fb(data->drm_fd, &fb);
}
static const struct edid *get_edid(enum test_edid edid);
@@ -530,10 +688,7 @@ prepare_output(data_t *data, struct chamelium_port *port, enum test_edid edid)
{
igt_display_t *display = &data->display;
igt_output_t *output;
- drmModeConnector *connector =
- chamelium_port_get_connector(data->chamelium, port, false);
enum pipe pipe;
- bool found = false;
/* The chamelium's default EDID has a lot of resolutions, way more then
* we need to test. Additionally the default EDID doesn't support HDMI
@@ -546,101 +701,17 @@ prepare_output(data_t *data, struct chamelium_port *port, enum test_edid edid)
igt_display_reset(display);
- output = igt_output_from_connector(display, connector);
+ output = get_output_for_port(data, port);
/* Refresh pipe to update connected status */
igt_output_set_pipe(output, PIPE_NONE);
- for_each_pipe(display, pipe) {
- if (!igt_pipe_connector_valid(pipe, output))
- continue;
-
- found = true;
- break;
- }
-
- igt_assert_f(found, "No pipe found for output %s\n", igt_output_name(output));
-
+ pipe = get_pipe_for_output(display, output);
igt_output_set_pipe(output, pipe);
- drmModeFreeConnector(connector);
-
return output;
}
-static void
-enable_output(data_t *data,
- struct chamelium_port *port,
- igt_output_t *output,
- drmModeModeInfo *mode,
- struct igt_fb *fb)
-{
- igt_display_t *display = output->display;
- igt_plane_t *primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
- drmModeConnector *connector = chamelium_port_get_connector(
- data->chamelium, port, false);
-
- igt_assert(primary);
-
- igt_plane_set_size(primary, mode->hdisplay, mode->vdisplay);
- igt_plane_set_fb(primary, fb);
- igt_output_override_mode(output, mode);
-
- /* Clear any color correction values that might be enabled */
- if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_DEGAMMA_LUT))
- igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_DEGAMMA_LUT, NULL, 0);
- if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_LUT))
- igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_GAMMA_LUT, NULL, 0);
- if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_CTM))
- igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_CTM, NULL, 0);
-
- igt_display_commit2(display, COMMIT_ATOMIC);
-
- if (chamelium_port_get_type(port) == DRM_MODE_CONNECTOR_VGA)
- usleep(250000);
-
- drmModeFreeConnector(connector);
-}
-
-static void chamelium_paint_xr24_pattern(uint32_t *data,
- size_t width, size_t height,
- size_t stride, size_t block_size)
-{
- uint32_t colors[] = { 0xff000000,
- 0xffff0000,
- 0xff00ff00,
- 0xff0000ff,
- 0xffffffff };
- unsigned i, j;
-
- for (i = 0; i < height; i++)
- for (j = 0; j < width; j++)
- *(data + i * stride / 4 + j) = colors[((j / block_size) + (i / block_size)) % 5];
-}
-
-static int chamelium_get_pattern_fb(data_t *data, size_t width, size_t height,
- uint32_t fourcc, size_t block_size,
- struct igt_fb *fb)
-{
- int fb_id;
- void *ptr;
-
- igt_assert(fourcc == DRM_FORMAT_XRGB8888);
-
- fb_id = igt_create_fb(data->drm_fd, width, height, fourcc,
- LOCAL_DRM_FORMAT_MOD_NONE, fb);
- igt_assert(fb_id > 0);
-
- ptr = igt_fb_map_buffer(fb->fd, fb);
- igt_assert(ptr);
-
- chamelium_paint_xr24_pattern(ptr, width, height, fb->strides[0],
- block_size);
- igt_fb_unmap_buffer(fb, ptr);
-
- return fb_id;
-}
-
static void do_test_display(data_t *data, struct chamelium_port *port,
igt_output_t *output, drmModeModeInfo *mode,
uint32_t fourcc, enum chamelium_check check,
@@ -2555,13 +2626,27 @@ igt_main
igt_describe(test_basic_hotplug_desc);
connector_subtest("dp-hpd", DisplayPort)
- test_basic_hotplug(&data, port,
- HPD_TOGGLE_COUNT_DP_HDMI);
+ test_hotplug(&data, port,
+ HPD_TOGGLE_COUNT_DP_HDMI,
+ TEST_MODESET_OFF);
igt_describe(test_basic_hotplug_desc);
connector_subtest("dp-hpd-fast", DisplayPort)
- test_basic_hotplug(&data, port,
- HPD_TOGGLE_COUNT_FAST);
+ test_hotplug(&data, port,
+ HPD_TOGGLE_COUNT_FAST,
+ TEST_MODESET_OFF);
+
+ igt_describe(test_basic_hotplug_desc);
+ connector_subtest("dp-hpd-enable-disable-mode", DisplayPort)
+ test_hotplug(&data, port,
+ HPD_TOGGLE_COUNT_FAST,
+ TEST_MODESET_ON_OFF);
+
+ igt_describe(test_basic_hotplug_desc);
+ connector_subtest("dp-hpd-with-enabled-mode", DisplayPort)
+ test_hotplug(&data, port,
+ HPD_TOGGLE_COUNT_FAST,
+ TEST_MODESET_ON);
igt_describe(test_edid_read_desc);
connector_subtest("dp-edid-read", DisplayPort) {
@@ -2650,13 +2735,27 @@ igt_main
igt_describe(test_basic_hotplug_desc);
connector_subtest("hdmi-hpd", HDMIA)
- test_basic_hotplug(&data, port,
- HPD_TOGGLE_COUNT_DP_HDMI);
+ test_hotplug(&data, port,
+ HPD_TOGGLE_COUNT_DP_HDMI,
+ TEST_MODESET_OFF);
igt_describe(test_basic_hotplug_desc);
connector_subtest("hdmi-hpd-fast", HDMIA)
- test_basic_hotplug(&data, port,
- HPD_TOGGLE_COUNT_FAST);
+ test_hotplug(&data, port,
+ HPD_TOGGLE_COUNT_FAST,
+ TEST_MODESET_OFF);
+
+ igt_describe(test_basic_hotplug_desc);
+ connector_subtest("hdmi-hpd-enable-disable-mode", HDMIA)
+ test_hotplug(&data, port,
+ HPD_TOGGLE_COUNT_FAST,
+ TEST_MODESET_ON_OFF);
+
+ igt_describe(test_basic_hotplug_desc);
+ connector_subtest("hdmi-hpd-with-enabled-mode", HDMIA)
+ test_hotplug(&data, port,
+ HPD_TOGGLE_COUNT_FAST,
+ TEST_MODESET_ON);
igt_describe(test_edid_read_desc);
connector_subtest("hdmi-edid-read", HDMIA) {
@@ -2811,11 +2910,25 @@ igt_main
igt_describe(test_basic_hotplug_desc);
connector_subtest("vga-hpd", VGA)
- test_basic_hotplug(&data, port, HPD_TOGGLE_COUNT_VGA);
+ test_hotplug(&data, port, HPD_TOGGLE_COUNT_VGA,
+ TEST_MODESET_OFF);
igt_describe(test_basic_hotplug_desc);
connector_subtest("vga-hpd-fast", VGA)
- test_basic_hotplug(&data, port, HPD_TOGGLE_COUNT_FAST);
+ test_hotplug(&data, port, HPD_TOGGLE_COUNT_FAST,
+ TEST_MODESET_OFF);
+
+ igt_describe(test_basic_hotplug_desc);
+ connector_subtest("vga-hpd-enable-disable-mode", VGA)
+ test_hotplug(&data, port,
+ HPD_TOGGLE_COUNT_FAST,
+ TEST_MODESET_ON_OFF);
+
+ igt_describe(test_basic_hotplug_desc);
+ connector_subtest("vga-hpd-with-enabled-mode", VGA)
+ test_hotplug(&data, port,
+ HPD_TOGGLE_COUNT_FAST,
+ TEST_MODESET_ON);
igt_describe(test_edid_read_desc);
connector_subtest("vga-edid-read", VGA) {