[igt-dev] [PATCH i-g-t v7 3/5] tests/i915_pm_lpsp: lpsp platform agnostic support

Nautiyal, Ankit K ankit.k.nautiyal at intel.com
Mon May 11 11:57:32 UTC 2020



On 5/7/2020 3:52 PM, Anshuman Gupta wrote:
> Current implementation of lpsp igt test, assumed that every non-edp
> panel isn't a lpsp panel but it is not true on TGL anymore,
> any HDMI/DP/DSI panel connected on pipe A and connected to PORT_{A,B,C}
> can drive LPSP.
> Even on older Gen9 platform a DP panel can drive lpsp on Port A.
> This requires complete design change in current lpsp igt for a platform
> agnostic support.
>
> The new igt approach is relies on connector specific
> i915_lpsp_capability and i915_lpsp_status debugfs attributes,
> these debugfs exposes whether an output is capable of driving lpsp
> and lpsp is enabled.
>
> Nuking edp-native and non-edp test, introducing a new dynamic
> igt subtest kms-lpsp, which validates lpsp on each connected output
> and skip the subtest if output is not lpsp capable.
>
> Skip screens-disabled test for platform which support DC states.
> screens-disabled test is only valid for the platforms like HSW/BDW
> where PG1 is Always-ON power domain, so these platform test lpsp
> with all screen disabled i.e validate PG2 when all screen are
> disabled.
> DC state i.e DMC f/w supported platforms don't have any ROI to validate
> screens-disabled subtest as existing dc*-dpms i915_pm_dc
> subtest already validate it implicitly.
>
> v2:
> - CI failures fixup.
> v3:
> - removed unloading of snd_modules. [Martin]
> v4:
> - Don't test non-lpsp(if lpsp disabled), no ROI to test that.
> - nuke panel-fitter test.
> v5:
> - Added dynamic subtest and igt changes according to kernel
>    debugfs i915_lpsp_status changes.
> v6:
> - Avoided pipe big joiner by using 4k or lesser mode,
>    so igt will not fail when pipe big joiner patches will
>    land to kernel.
> v7:
> - Combined [v6 4/6] patch to this patch, skip the screens-disabled
>    subtest for DC state supported platforms. [Animesh]
>
> Signed-off-by: Anshuman Gupta <anshuman.gupta at intel.com>
> ---
>   tests/i915/i915_pm_lpsp.c | 313 ++++++++++++++++++--------------------
>   1 file changed, 147 insertions(+), 166 deletions(-)
>
> diff --git a/tests/i915/i915_pm_lpsp.c b/tests/i915/i915_pm_lpsp.c
> index 08f82e7c..46937efb 100644
> --- a/tests/i915/i915_pm_lpsp.c
> +++ b/tests/i915/i915_pm_lpsp.c
> @@ -25,210 +25,191 @@
>    */
>   
>   #include "igt.h"
> +#include "igt_kmod.h"
> +#include "igt_pm.h"
> +#include "igt_sysfs.h"
>   #include <sys/types.h>
>   #include <sys/stat.h>
>   #include <fcntl.h>
>   #include <unistd.h>
>   
> +#define MAX_SINK_LPSP_INFO_BUF_LEN	4096
>   
> -static bool supports_lpsp(uint32_t devid)
> -{
> -	return IS_HASWELL(devid) || IS_BROADWELL(devid);
> -}
> +#define PWR_DOMAIN_INFO "i915_power_domain_info"
>   
> -static bool lpsp_is_enabled(int drm_fd)
> +typedef struct {
> +	int drm_fd;
> +	int debugfs_fd;
> +	uint32_t devid;
> +	char *pwr_dmn_info;
> +	igt_display_t display;
> +	struct igt_fb fb;
> +	drmModeModeInfo *mode;
> +	igt_output_t *output;
> +} data_t;
> +
> +static bool lpsp_is_enabled(data_t *data)
>   {
> -	uint32_t val;
> +	char buf[MAX_SINK_LPSP_INFO_BUF_LEN];
> +	int len;
>   
> -	val = INREG(HSW_PWR_WELL_CTL2);
> -	return !(val & HSW_PWR_WELL_STATE_ENABLED);
> -}
> +	len = igt_debugfs_simple_read(data->debugfs_fd, "i915_lpsp_status",
> +				      buf, sizeof(buf));
> +	if (len < 0)
> +		igt_assert_eq(len, -ENODEV);
>   
> -/* The LPSP mode is all about an enabled pipe, but we expect to also be in the
> - * low power mode when no pipes are enabled, so do this check anyway. */
> -static void screens_disabled_subtest(int drm_fd, drmModeResPtr drm_res)
> -{
> -	kmstest_unset_all_crtcs(drm_fd, drm_res);
> -	igt_assert(lpsp_is_enabled(drm_fd));
> +	igt_skip_on(strstr(buf, "LPSP: not supported"));
> +
> +	return strstr(buf, "LPSP: enabled");
>   }
>   
> -static uint32_t create_fb(int drm_fd, int width, int height)
> +static bool dmc_supported(int debugfs)
>   {
> -	struct igt_fb fb;
> +	char buf[15];
> +	int len;
>   
> -	return igt_create_pattern_fb(drm_fd, width, height, DRM_FORMAT_XRGB8888,
> -				     LOCAL_DRM_FORMAT_MOD_NONE, &fb);
> +	len = igt_sysfs_read(debugfs, "i915_dmc_info", buf, sizeof(buf) - 1);
> +
> +	if (len < 0)
> +		return false;
> +	else
> +		return true;
>   }
>   
> -static void edp_subtest(int drm_fd, drmModeResPtr drm_res,
> -			drmModeConnectorPtr *drm_connectors, uint32_t devid,
> -			bool use_panel_fitter)
> +/*
> + * The LPSP mode is all about an enabled pipe, but we expect to also be in the
> + * low power mode when no pipes are enabled, so do this check anyway.
> + */
> +static void screens_disabled_subtest(data_t *data)
>   {
> -	int i, rc;
> -	uint32_t crtc_id = 0, buffer_id = 0;
> -	drmModeConnectorPtr connector = NULL;
> -	drmModeModeInfoPtr mode = NULL;
> -	drmModeModeInfo std_1024_mode = {
> -		.clock = 65000,
> -		.hdisplay = 1024,
> -		.hsync_start = 1048,
> -		.hsync_end = 1184,
> -		.htotal = 1344,
> -		.hskew = 0,
> -		.vdisplay = 768,
> -		.vsync_start = 771,
> -		.vsync_end = 777,
> -		.vtotal = 806,
> -		.vscan = 0,
> -		.vrefresh = 60,
> -		.flags = 0xA,
> -		.type = 0x40,
> -		.name = "Custom 1024x768",
> -	};
> -
> -	kmstest_unset_all_crtcs(drm_fd, drm_res);
> -
> -	for (i = 0; i < drm_res->count_connectors; i++) {
> -		drmModeConnectorPtr c = drm_connectors[i];
> -
> -		if (c->connector_type != DRM_MODE_CONNECTOR_eDP)
> -			continue;
> -		if (c->connection != DRM_MODE_CONNECTED)
> -			continue;
> -
> -		if (!use_panel_fitter && c->count_modes) {
> -			connector = c;
> -			mode = &c->modes[0];
> -			break;
> -		}
> -		if (use_panel_fitter) {
> -			connector = c;
> -
> -			/* This is one of the modes Xorg creates for panels, so
> -			 * it should work just fine. Notice that Gens that
> -			 * support LPSP are too new for panels with native
> -			 * 1024x768 resolution, so this should force the panel
> -			 * fitter. */
> -			igt_assert(c->count_modes &&
> -				   c->modes[0].hdisplay > 1024);
> -			igt_assert(c->count_modes &&
> -				   c->modes[0].vdisplay > 768);
> -			mode = &std_1024_mode;
> -			break;
> -		}
> -	}
> -	igt_require(connector);
> -
> -	crtc_id = kmstest_find_crtc_for_connector(drm_fd, drm_res, connector,
> -						  0);
> -	buffer_id = create_fb(drm_fd, mode->hdisplay, mode->vdisplay);
> -
> -	igt_assert(buffer_id);
> -	igt_assert(connector);
> -	igt_assert(mode);
> -
> -	rc = drmModeSetCrtc(drm_fd, crtc_id, buffer_id, 0, 0,
> -			    &connector->connector_id, 1, mode);
> -	igt_assert_eq(rc, 0);
> -
> -	if (use_panel_fitter) {
> -		if (IS_HASWELL(devid))
> -			igt_assert(!lpsp_is_enabled(drm_fd));
> -		else
> -			igt_assert(lpsp_is_enabled(drm_fd));
> -	} else {
> -		igt_assert(lpsp_is_enabled(drm_fd));
> +	igt_output_t *output;
> +	int valid_output = 0;
> +	enum pipe pipe;
> +
> +	for_each_pipe_with_single_output(&data->display, pipe, output) {
> +		data->output = output;
> +		igt_output_set_pipe(data->output, PIPE_NONE);
> +		igt_display_commit(&data->display);
> +		valid_output++;
>   	}
> +
> +	igt_require_f(valid_output, "No connected output found\n");
> +	igt_assert_f(lpsp_is_enabled(data), "lpsp is not enabled\n%s:\n%s\n",
> +		     PWR_DOMAIN_INFO, data->pwr_dmn_info =
> +		     igt_sysfs_get(data->debugfs_fd, PWR_DOMAIN_INFO));
>   }
>   
> -static void non_edp_subtest(int drm_fd, drmModeResPtr drm_res,
> -			    drmModeConnectorPtr *drm_connectors)
> +static void setup_lpsp_output(data_t *data)
>   {
> -	int i, rc;
> -	uint32_t crtc_id = 0, buffer_id = 0;
> -	drmModeConnectorPtr connector = NULL;
> -	drmModeModeInfoPtr mode = NULL;
> -
> -	kmstest_unset_all_crtcs(drm_fd, drm_res);
> -
> -	for (i = 0; i < drm_res->count_connectors; i++) {
> -		drmModeConnectorPtr c = drm_connectors[i];
> +	igt_plane_t *primary;
> +
> +	/* set output pipe = PIPE_A for LPSP */
> +	igt_output_set_pipe(data->output, PIPE_A);
> +	primary = igt_output_get_plane_type(data->output,
> +					    DRM_PLANE_TYPE_PRIMARY);
> +	igt_plane_set_fb(primary, NULL);
> +	igt_create_pattern_fb(data->drm_fd,
> +			      data->mode->hdisplay, data->mode->vdisplay,
> +			      DRM_FORMAT_XRGB8888,
> +			      LOCAL_DRM_FORMAT_MOD_NONE,
> +			      &data->fb);
> +	igt_plane_set_fb(primary, &data->fb);
> +	igt_display_commit(&data->display);
> +}
>   
> -		if (c->connector_type == DRM_MODE_CONNECTOR_eDP)
> -			continue;
> -		if (c->connection != DRM_MODE_CONNECTED)
> -			continue;
> +static void test_cleanup(data_t *data)
> +{
> +	igt_plane_t *primary;
> +
> +	if (!data->output || data->output->pending_pipe == PIPE_NONE)
> +		return;
> +
> +	primary = igt_output_get_plane_type(data->output,
> +					    DRM_PLANE_TYPE_PRIMARY);
> +	igt_plane_set_fb(primary, NULL);
> +	igt_output_set_pipe(data->output, PIPE_NONE);
> +	igt_display_commit(&data->display);
> +	igt_remove_fb(data->drm_fd, &data->fb);
> +	data->output = NULL;
> +}
>   
> -		if (c->count_modes) {
> -			connector = c;
> -			mode = &c->modes[0];
> -			break;
> +static void test_lpsp(data_t *data)
> +{
> +	drmModeConnectorPtr c = data->output->config.connector;
> +	int i;
> +
> +	/* LPSP is low power single pipe usages i.e. PIPE_A */
> +	igt_require(igt_pipe_connector_valid(PIPE_A, data->output));
> +	igt_require_f(i915_output_is_lpsp_capable(data->drm_fd, data->output),
> +		      "output is not lpsp capable\n");
> +
> +	data->mode = igt_output_get_mode(data->output);
> +
> +	/* For LPSP avoid pipe big joiner by atleast 4k mode */
> +	if (data->mode->hdisplay > 3860 && data->mode->vdisplay > 2160)


For 4K mode the resolution is either 4096 x 2160 or 3840 x 2160.
should the hdisplay be 3840 instead?

Also, should we check from the first mode, not sure if the first mode is 
always the default mode.

Regards,
Ankit
> +		for (i = 1; i < c->count_modes; i++) {
> +			if (c->modes[i].hdisplay <= 3860 &&
> +			    c->modes[i].vdisplay <= 2160) {
> +				data->mode = &c->modes[i];
> +				igt_output_override_mode(data->output,
> +							 data->mode);
> +				break;
> +			}
>   		}
> -	}
> -	igt_require(connector);
> -
> -	crtc_id = kmstest_find_crtc_for_connector(drm_fd, drm_res, connector,
> -						  0);
> -	buffer_id = create_fb(drm_fd, mode->hdisplay, mode->vdisplay);
> -
> -	igt_assert(buffer_id);
> -	igt_assert(mode);
>   
> -	rc = drmModeSetCrtc(drm_fd, crtc_id, buffer_id, 0, 0,
> -			    &connector->connector_id, 1, mode);
> -	igt_assert_eq(rc, 0);
> +	igt_require(data->mode->hdisplay <= 3860 &&
> +		    data->mode->vdisplay <= 2160);
>   
> -	igt_assert(!lpsp_is_enabled(drm_fd));
> +	setup_lpsp_output(data);
> +	igt_assert_f(lpsp_is_enabled(data), "%s: lpsp is not enabled\n%s:\n%s\n",
> +		     data->output->name, PWR_DOMAIN_INFO, data->pwr_dmn_info =
> +		     igt_sysfs_get(data->debugfs_fd, PWR_DOMAIN_INFO));
>   }
>   
> -#define MAX_CONNECTORS 32
> -
> -int drm_fd;
> -uint32_t devid;
> -drmModeResPtr drm_res;
> -drmModeConnectorPtr drm_connectors[MAX_CONNECTORS];
> -struct intel_mmio_data mmio_data;
> +IGT_TEST_DESCRIPTION("These tests validates display Low Power Single Pipe configurations");
>   igt_main
>   {
> -	igt_fixture {
> -		int i;
> -
> -		drm_fd = drm_open_driver_master(DRIVER_INTEL);
> -		igt_require(drm_fd >= 0);
> -
> -		devid = intel_get_drm_devid(drm_fd);
> -
> -		drm_res = drmModeGetResources(drm_fd);
> -		igt_require(drm_res);
> -		igt_assert(drm_res->count_connectors <= MAX_CONNECTORS);
> +	data_t data = {};
>   
> -		for (i = 0; i < drm_res->count_connectors; i++)
> -			drm_connectors[i] = drmModeGetConnectorCurrent(drm_fd,
> -							drm_res->connectors[i]);
> +	igt_fixture {
>   
> +		data.drm_fd = drm_open_driver_master(DRIVER_INTEL);
> +		igt_require(data.drm_fd >= 0);
> +		data.debugfs_fd = igt_debugfs_dir(data.drm_fd);
> +		igt_require(data.debugfs_fd >= 0);
>   		igt_pm_enable_audio_runtime_pm();
> +		kmstest_set_vt_graphics_mode();
> +		data.devid = intel_get_drm_devid(data.drm_fd);
> +		igt_display_require(&data.display, data.drm_fd);
> +		igt_require(igt_pm_dmc_loaded(data.debugfs_fd));
> +	}
>   
> -		igt_require(supports_lpsp(devid));
> +	igt_describe("This test validates lpsp while all crtc are disabled");
> +	igt_subtest("screens-disabled") {
> +		igt_require_f(!dmc_supported(data.debugfs_fd),
> +			      "DC states supported platform don't have ROI for this subtest\n");
> +		screens_disabled_subtest(&data);
> +	}
>   
> -		intel_register_access_init(&mmio_data, intel_get_pci_device(), 0, drm_fd);
> +	igt_describe("This test validates lpsp on all connected outputs on low power PIPE_A");
> +	igt_subtest_with_dynamic_f("kms-lpsp") {
> +		igt_display_t *display = &data.display;
> +		igt_output_t *output;
>   
> -		kmstest_set_vt_graphics_mode();
> -	}
> +		for_each_connected_output(display, output) {
> +			igt_dynamic_f("kms-lpsp-%s",
> +				      kmstest_connector_type_str(output->config.connector->connector_type)) {
> +				data.output = output;
> +				test_lpsp(&data);
> +			}
>   
> -	igt_subtest("screens-disabled")
> -		screens_disabled_subtest(drm_fd, drm_res);
> -	igt_subtest("edp-native")
> -		edp_subtest(drm_fd, drm_res, drm_connectors, devid, false);
> -	igt_subtest("non-edp")
> -		non_edp_subtest(drm_fd, drm_res, drm_connectors);
> +			test_cleanup(&data);
> +		}
> +	}
>   
>   	igt_fixture {
> -		int i;
> -
> -		intel_register_access_fini(&mmio_data);
> -		for (i = 0; i < drm_res->count_connectors; i++)
> -			drmModeFreeConnector(drm_connectors[i]);
> -		drmModeFreeResources(drm_res);
> -		close(drm_fd);
> +		free(data.pwr_dmn_info);
> +		close(data.drm_fd);
> +		igt_display_fini(&data.display);
>   	}
>   }



More information about the igt-dev mailing list