lib/igt_kms: Unify pipe name helpers
[platform/upstream/intel-gpu-tools.git] / tests / pm_lpsp.c
1 /*
2  * Copyright © 2013 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  * Author: Paulo Zanoni <paulo.r.zanoni@intel.com>
24  *
25  */
26
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31
32 #include "drmtest.h"
33 #include "igt_kms.h"
34 #include "intel_io.h"
35 #include "intel_chipset.h"
36
37 /* We know that if we don't enable audio runtime PM, snd_hda_intel will never
38  * release its power well refcount, and we'll never reach the LPSP sate. OTOH
39  * there's no guarantee that it will release the power well if we enable runtime
40  * PM, but at least we can try.  We don't have any assertions since the user may
41  * not even have snd_hda_intel loaded, which is not a problem. */
42 static void disable_audio_runtime_pm(void)
43 {
44         int fd;
45
46         fd = open("/sys/module/snd_hda_intel/parameters/power_save", O_WRONLY);
47         if (fd >= 0) {
48                 write(fd, "1\n", 2);
49                 close(fd);
50         }
51         fd = open("/sys/bus/pci/devices/0000:00:03.0/power/control", O_WRONLY);
52         if (fd >= 0) {
53                 write(fd, "auto\n", 5);
54                 close(fd);
55         }
56         /* Give some time for it to react. */
57         sleep(1);
58 }
59
60 static bool supports_lpsp(uint32_t devid)
61 {
62         return IS_HASWELL(devid) || IS_BROADWELL(devid);
63 }
64
65 static bool lpsp_is_enabled(int drm_fd)
66 {
67         uint32_t val;
68
69         val = INREG(HSW_PWR_WELL_CTL2);
70         return !(val & HSW_PWR_WELL_STATE_ENABLED);
71 }
72
73 /* The LPSP mode is all about an enabled pipe, but we expect to also be in the
74  * low power mode when no pipes are enabled, so do this check anyway. */
75 static void screens_disabled_subtest(int drm_fd, drmModeResPtr drm_res)
76 {
77         kmstest_unset_all_crtcs(drm_fd, drm_res);
78         igt_assert(lpsp_is_enabled(drm_fd));
79 }
80
81 static uint32_t create_fb(int drm_fd, int width, int height)
82 {
83         struct igt_fb fb;
84         cairo_t *cr;
85         uint32_t buffer_id;
86
87         buffer_id = igt_create_fb(drm_fd, width, height,
88                                       DRM_FORMAT_XRGB8888,
89                                       false, &fb);
90         cr = igt_get_cairo_ctx(drm_fd, &fb);
91         igt_paint_test_pattern(cr, width, height);
92         cairo_destroy(cr);
93
94         return buffer_id;
95 }
96
97 static void edp_subtest(int drm_fd, drmModeResPtr drm_res,
98                         drmModeConnectorPtr *drm_connectors, uint32_t devid,
99                         bool use_panel_fitter)
100 {
101         int i, rc;
102         uint32_t connector_id = 0, crtc_id = 0, buffer_id = 0;
103         drmModeModeInfoPtr mode = NULL;
104         drmModeModeInfo std_1024_mode = {
105                 .clock = 65000,
106                 .hdisplay = 1024,
107                 .hsync_start = 1048,
108                 .hsync_end = 1184,
109                 .htotal = 1344,
110                 .vtotal = 806,
111                 .hskew = 0,
112                 .vdisplay = 768,
113                 .vsync_start = 771,
114                 .vsync_end = 777,
115                 .vtotal = 806,
116                 .vscan = 0,
117                 .vrefresh = 60,
118                 .flags = 0xA,
119                 .type = 0x40,
120                 .name = "Custom 1024x768",
121         };
122
123         kmstest_unset_all_crtcs(drm_fd, drm_res);
124
125         for (i = 0; i < drm_res->count_connectors; i++) {
126                 drmModeConnectorPtr c = drm_connectors[i];
127
128                 if (c->connector_type != DRM_MODE_CONNECTOR_eDP)
129                         continue;
130                 if (c->connection != DRM_MODE_CONNECTED)
131                         continue;
132
133                 if (!use_panel_fitter && c->count_modes) {
134                         connector_id = c->connector_id;
135                         mode = &c->modes[0];
136                         break;
137                 }
138                 if (use_panel_fitter) {
139                         connector_id = c->connector_id;
140
141                         /* This is one of the modes Xorg creates for panels, so
142                          * it should work just fine. Notice that Gens that
143                          * support LPSP are too new for panels with native
144                          * 1024x768 resolution, so this should force the panel
145                          * fitter. */
146                         igt_assert(c->count_modes &&
147                                    c->modes[0].hdisplay > 1024);
148                         igt_assert(c->count_modes &&
149                                    c->modes[0].vdisplay > 768);
150                         mode = &std_1024_mode;
151                         break;
152                 }
153         }
154         igt_require(connector_id);
155
156         crtc_id = drm_res->crtcs[0];
157         buffer_id = create_fb(drm_fd, mode->hdisplay, mode->vdisplay);
158
159         igt_assert(crtc_id);
160         igt_assert(buffer_id);
161         igt_assert(connector_id);
162         igt_assert(mode);
163
164         rc = drmModeSetCrtc(drm_fd, crtc_id, buffer_id, 0, 0, &connector_id, 1,
165                             mode);
166         igt_assert(rc == 0);
167
168         if (use_panel_fitter) {
169                 if (IS_HASWELL(devid))
170                         igt_assert(!lpsp_is_enabled(drm_fd));
171                 else
172                         igt_assert(lpsp_is_enabled(drm_fd));
173         } else {
174                 igt_assert(lpsp_is_enabled(drm_fd));
175         }
176 }
177
178 static void non_edp_subtest(int drm_fd, drmModeResPtr drm_res,
179                             drmModeConnectorPtr *drm_connectors)
180 {
181         int i, rc;
182         uint32_t connector_id = 0, crtc_id = 0, buffer_id = 0;
183         drmModeModeInfoPtr mode = NULL;
184
185         kmstest_unset_all_crtcs(drm_fd, drm_res);
186
187         for (i = 0; i < drm_res->count_connectors; i++) {
188                 drmModeConnectorPtr c = drm_connectors[i];
189
190                 if (c->connector_type == DRM_MODE_CONNECTOR_eDP)
191                         continue;
192                 if (c->connection != DRM_MODE_CONNECTED)
193                         continue;
194
195                 if (c->count_modes) {
196                         connector_id = c->connector_id;
197                         mode = &c->modes[0];
198                         break;
199                 }
200         }
201         igt_require(connector_id);
202
203         crtc_id = drm_res->crtcs[0];
204         buffer_id = create_fb(drm_fd, mode->hdisplay, mode->vdisplay);
205
206         igt_assert(crtc_id);
207         igt_assert(buffer_id);
208         igt_assert(connector_id);
209         igt_assert(mode);
210
211         rc = drmModeSetCrtc(drm_fd, crtc_id, buffer_id, 0, 0, &connector_id, 1,
212                             mode);
213         igt_assert(rc == 0);
214
215         igt_assert(!lpsp_is_enabled(drm_fd));
216 }
217
218 #define MAX_CONNECTORS 32
219
220 int drm_fd;
221 uint32_t devid;
222 drmModeResPtr drm_res;
223 drmModeConnectorPtr drm_connectors[MAX_CONNECTORS];
224
225 igt_main
226 {
227         igt_fixture {
228                 int i;
229
230                 drm_fd = drm_open_any();
231                 igt_require(drm_fd >= 0);
232
233                 devid = intel_get_drm_devid(drm_fd);
234
235                 drm_res = drmModeGetResources(drm_fd);
236                 igt_assert(drm_res->count_connectors <= MAX_CONNECTORS);
237
238                 for (i = 0; i < drm_res->count_connectors; i++)
239                         drm_connectors[i] = drmModeGetConnector(drm_fd,
240                                                         drm_res->connectors[i]);
241
242                 disable_audio_runtime_pm();
243
244                 igt_require(supports_lpsp(devid));
245
246                 intel_register_access_init(intel_get_pci_device(), 0);
247
248                 igt_set_vt_graphics_mode();
249         }
250
251         igt_subtest("screens-disabled")
252                 screens_disabled_subtest(drm_fd, drm_res);
253         igt_subtest("edp-native")
254                 edp_subtest(drm_fd, drm_res, drm_connectors, devid, false);
255         igt_subtest("edp-panel-fitter")
256                 edp_subtest(drm_fd, drm_res, drm_connectors, devid, true);
257         igt_subtest("non-edp")
258                 non_edp_subtest(drm_fd, drm_res, drm_connectors);
259
260         igt_fixture {
261                 int i;
262
263                 intel_register_access_fini();
264                 for (i = 0; i < drm_res->count_connectors; i++)
265                         drmModeFreeConnector(drm_connectors[i]);
266                 drmModeFreeResources(drm_res);
267                 close(drm_fd);
268         }
269 }