diff options
author | Anshuman Gupta <anshuman.gupta@intel.com> | 2020-05-12 16:04:12 +0530 |
---|---|---|
committer | Swati Sharma <swati2.sharma@intel.com> | 2020-05-18 17:28:17 +0530 |
commit | 2c6dfecee0ec9fed6370fc7673d85cf0414e5033 (patch) | |
tree | bdceaac8a218b616c188a21dfa4c37c0d55d91b1 /tests/i915/i915_pm_lpsp.c | |
parent | 47d34be48381f6f9b6b451affabfe196e3a1f024 (diff) |
tests/i915_pm_lpsp: lpsp platform agnostic support
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]
v8:
- 4k mode correction 3840*2160 and for loop for available modes
should iterate from c->modes[0]. [Ankit]
Reviewed-by: Animesh Manna <animesh.manna@intel.com>
Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
Acked-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Diffstat (limited to 'tests/i915/i915_pm_lpsp.c')
-rw-r--r-- | tests/i915/i915_pm_lpsp.c | 313 |
1 files changed, 147 insertions, 166 deletions
diff --git a/tests/i915/i915_pm_lpsp.c b/tests/i915/i915_pm_lpsp.c index 08f82e7cf..0e9452fdd 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 > 3840 && data->mode->vdisplay > 2160) + for (i = 0; i < c->count_modes; i++) { + if (c->modes[i].hdisplay <= 3840 && + 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 <= 3840 && + 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); } } |