From mboxrd@z Thu Jan 1 00:00:00 1970 From: Paulo Zanoni Subject: [PATCH IGT] tests: add pm_lpsp Date: Tue, 3 Dec 2013 19:48:54 -0200 Message-ID: <1386107334-2040-1-git-send-email-przanoni@gmail.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0210010026==" Return-path: Received: from mail-qc0-f173.google.com (mail-qc0-f173.google.com [209.85.216.173]) by gabe.freedesktop.org (Postfix) with ESMTP id E704A1058AD for ; Tue, 3 Dec 2013 13:49:02 -0800 (PST) Received: by mail-qc0-f173.google.com with SMTP id m20so1310670qcx.4 for ; Tue, 03 Dec 2013 13:49:02 -0800 (PST) List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org To: intel-gfx@lists.freedesktop.org Cc: Paulo Zanoni List-Id: intel-gfx@lists.freedesktop.org --===============0210010026== Content-Type: text/plain; charset=y Content-Transfer-Encoding: quoted-printable From: Paulo Zanoni QA has asked me "How can we make sure LPSP is working?". Now, instead of writing big paragraphs, I can just answer "make sure pm_lpsp works". Signed-off-by: Paulo Zanoni --- tests/.gitignore | 1 + tests/Makefile.sources | 1 + tests/pm_lpsp.c | 275 +++++++++++++++++++++++++++++++++++++++++++= ++++++ 3 files changed, 277 insertions(+) create mode 100644 tests/pm_lpsp.c diff --git a/tests/.gitignore b/tests/.gitignore index 1bab1cb..6086e9c 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -108,6 +108,7 @@ kms_flip kms_pipe_crc_basic kms_render kms_setmode +pm_lpsp pm_pc8 pm_psr pm_rc6_residency diff --git a/tests/Makefile.sources b/tests/Makefile.sources index d201809..808bf35 100644 --- a/tests/Makefile.sources +++ b/tests/Makefile.sources @@ -54,6 +54,7 @@ TESTS_progs_M =3D \ kms_pipe_crc_basic \ kms_render \ kms_setmode \ + pm_lpsp \ pm_pc8 \ prime_self_import \ template \ diff --git a/tests/pm_lpsp.c b/tests/pm_lpsp.c new file mode 100644 index 0000000..492efe1 --- /dev/null +++ b/tests/pm_lpsp.c @@ -0,0 +1,275 @@ +/* + * Copyright =C2=A9 2013 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining= a + * copy of this software and associated documentation files (the "Softwa= re"), + * to deal in the Software without restriction, including without limita= tion + * the rights to use, copy, modify, merge, publish, distribute, sublicen= se, + * 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, EXPRE= SS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILI= TY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SH= ALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR = OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISI= NG + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER D= EALINGS + * IN THE SOFTWARE. + * + * Author: Paulo Zanoni + * + */ + +#include +#include +#include +#include + +#include "drmtest.h" +#include "igt_kms.h" + +/* We know that if we don't enable audio runtime PM, snd_hda_intel will = never + * release its power well refcount, and we'll never reach the LPSP sate.= OTOH + * there's no guarantee that it will release the power well if we enable= runtime + * PM, but at least we can try. We don't have any assertions since the = user may + * not even have snd_hda_intel loaded, which is not a problem. */ +static void disable_audio_runtime_pm(void) +{ + int fd; + + fd =3D open("/sys/module/snd_hda_intel/parameters/power_save", O_WRONLY= ); + if (fd >=3D 0) { + write(fd, "1\n", 2); + close(fd); + } + fd =3D open("/sys/bus/pci/devices/0000:00:03.0/power/control", O_WRONLY= ); + if (fd >=3D 0) { + write(fd, "auto\n", 5); + close(fd); + } + /* Give some time for it to react. */ + sleep(1); +} + +static bool supports_lpsp(uint32_t devid) +{ + return IS_HASWELL(devid) || IS_BROADWELL(devid); +} + +static bool lpsp_is_enabled(int drm_fd) +{ + uint32_t val; + + val =3D INREG(HSW_PWR_WELL_CTL2); + return !(val & HSW_PWR_WELL_STATE_ENABLED); +} + +static void disable_all_screens(int drm_fd, drmModeResPtr drm_resources) +{ + int i, rc; + + for (i =3D 0; i < drm_resources->count_crtcs; i++) { + rc =3D drmModeSetCrtc(drm_fd, drm_resources->crtcs[i], -1, 0, 0, + NULL, 0, NULL); + igt_assert(rc =3D=3D 0); + } +} + +/* 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) +{ + disable_all_screens(drm_fd, drm_res); + igt_assert(lpsp_is_enabled(drm_fd)); +} + +static uint32_t create_fb(int drm_fd, int width, int height) +{ + struct kmstest_fb fb; + cairo_t *cr; + uint32_t buffer_id; + + buffer_id =3D kmstest_create_fb(drm_fd, width, height, 32, 24, false, + &fb); + cr =3D kmstest_get_cairo_ctx(drm_fd, &fb); + kmstest_paint_test_pattern(cr, width, height); + return buffer_id; +} + +static void edp_subtest(int drm_fd, drmModeResPtr drm_res, + drmModeConnectorPtr *drm_connectors, uint32_t devid, + bool use_panel_fitter) +{ + int i, rc; + uint32_t connector_id =3D 0, crtc_id =3D 0, buffer_id =3D 0; + drmModeModeInfoPtr mode =3D NULL; + drmModeModeInfo std_1024_mode =3D { + .clock =3D 65000, + .hdisplay =3D 1024, + .hsync_start =3D 1048, + .hsync_end =3D 1184, + .htotal =3D 1344, + .vtotal =3D 806, + .hskew =3D 0, + .vdisplay =3D 768, + .vsync_start =3D 771, + .vsync_end =3D 777, + .vtotal =3D 806, + .vscan =3D 0, + .vrefresh =3D 60, + .flags =3D 0xA, + .type =3D 0x40, + .name =3D "Custom 1024x768", + }; + + disable_all_screens(drm_fd, drm_res); + + for (i =3D 0; i < drm_res->count_connectors; i++) { + drmModeConnectorPtr c =3D drm_connectors[i]; + + if (c->connector_type !=3D DRM_MODE_CONNECTOR_eDP) + continue; + if (c->connection !=3D DRM_MODE_CONNECTED) + continue; + + if (!use_panel_fitter && c->count_modes) { + connector_id =3D c->connector_id; + mode =3D &c->modes[0]; + break; + } + if (use_panel_fitter) { + connector_id =3D c->connector_id; + + /* 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 =3D &std_1024_mode; + break; + } + } + igt_require(connector_id); + + crtc_id =3D drm_res->crtcs[0]; + buffer_id =3D create_fb(drm_fd, mode->hdisplay, mode->vdisplay); + + igt_assert(crtc_id); + igt_assert(buffer_id); + igt_assert(connector_id); + igt_assert(mode); + + rc =3D drmModeSetCrtc(drm_fd, crtc_id, buffer_id, 0, 0, &connector_id, = 1, + mode); + igt_assert(rc =3D=3D 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)); + } +} + +static void non_edp_subtest(int drm_fd, drmModeResPtr drm_res, + drmModeConnectorPtr *drm_connectors) +{ + int i, rc; + uint32_t connector_id =3D 0, crtc_id =3D 0, buffer_id =3D 0; + drmModeModeInfoPtr mode =3D NULL; + + disable_all_screens(drm_fd, drm_res); + + for (i =3D 0; i < drm_res->count_connectors; i++) { + drmModeConnectorPtr c =3D drm_connectors[i]; + + if (c->connector_type =3D=3D DRM_MODE_CONNECTOR_eDP) + continue; + if (c->connection !=3D DRM_MODE_CONNECTED) + continue; + + if (c->count_modes) { + connector_id =3D c->connector_id; + mode =3D &c->modes[0]; + break; + } + } + igt_require(connector_id); + + crtc_id =3D drm_res->crtcs[0]; + buffer_id =3D create_fb(drm_fd, mode->hdisplay, mode->vdisplay); + + igt_assert(crtc_id); + igt_assert(buffer_id); + igt_assert(connector_id); + igt_assert(mode); + + rc =3D drmModeSetCrtc(drm_fd, crtc_id, buffer_id, 0, 0, &connector_id, = 1, + mode); + igt_assert(rc =3D=3D 0); + + igt_assert(!lpsp_is_enabled(drm_fd)); +} + +#define MAX_CONNECTORS 32 + +int drm_fd; +uint32_t devid; +drmModeResPtr drm_res; +drmModeConnectorPtr drm_connectors[MAX_CONNECTORS]; + +igt_main +{ + igt_fixture { + int i; + + drm_fd =3D drm_open_any(); + igt_require(drm_fd >=3D 0); + + devid =3D intel_get_drm_devid(drm_fd); + + drm_res =3D drmModeGetResources(drm_fd); + igt_assert(drm_res->count_connectors <=3D MAX_CONNECTORS); + + for (i =3D 0; i < drm_res->count_connectors; i++) + drm_connectors[i] =3D drmModeGetConnector(drm_fd, + drm_res->connectors[i]); + + disable_audio_runtime_pm(); + + igt_require(supports_lpsp(devid)); + + intel_register_access_init(intel_get_pci_device(), 0); + + igt_set_vt_graphics_mode(); + } + + 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("edp-panel-fitter") + edp_subtest(drm_fd, drm_res, drm_connectors, devid, true); + igt_subtest("non-edp") + non_edp_subtest(drm_fd, drm_res, drm_connectors); + + igt_fixture { + int i; + + intel_register_access_fini(); + for (i =3D 0; i < drm_res->count_connectors; i++) + drmModeFreeConnector(drm_connectors[i]); + drmModeFreeResources(drm_res); + close(drm_fd); + } +} --=20 1.8.3.1 --===============0210010026== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx --===============0210010026==--