igt/gem_userptr_blits: Fix forked access test
[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 static void disable_all_screens(int drm_fd, drmModeResPtr drm_resources)
74 {
75         int i, rc;
76
77         for (i = 0; i < drm_resources->count_crtcs; i++) {
78                 rc = drmModeSetCrtc(drm_fd, drm_resources->crtcs[i], -1, 0, 0,
79                                     NULL, 0, NULL);
80                 igt_assert(rc == 0);
81         }
82 }
83
84 /* The LPSP mode is all about an enabled pipe, but we expect to also be in the
85  * low power mode when no pipes are enabled, so do this check anyway. */
86 static void screens_disabled_subtest(int drm_fd, drmModeResPtr drm_res)
87 {
88         disable_all_screens(drm_fd, drm_res);
89         igt_assert(lpsp_is_enabled(drm_fd));
90 }
91
92 static uint32_t create_fb(int drm_fd, int width, int height)
93 {
94         struct igt_fb fb;
95         cairo_t *cr;
96         uint32_t buffer_id;
97
98         buffer_id = igt_create_fb(drm_fd, width, height,
99                                       DRM_FORMAT_XRGB8888,
100                                       false, &fb);
101         cr = igt_get_cairo_ctx(drm_fd, &fb);
102         igt_paint_test_pattern(cr, width, height);
103         cairo_destroy(cr);
104
105         return buffer_id;
106 }
107
108 static void edp_subtest(int drm_fd, drmModeResPtr drm_res,
109                         drmModeConnectorPtr *drm_connectors, uint32_t devid,
110                         bool use_panel_fitter)
111 {
112         int i, rc;
113         uint32_t connector_id = 0, crtc_id = 0, buffer_id = 0;
114         drmModeModeInfoPtr mode = NULL;
115         drmModeModeInfo std_1024_mode = {
116                 .clock = 65000,
117                 .hdisplay = 1024,
118                 .hsync_start = 1048,
119                 .hsync_end = 1184,
120                 .htotal = 1344,
121                 .vtotal = 806,
122                 .hskew = 0,
123                 .vdisplay = 768,
124                 .vsync_start = 771,
125                 .vsync_end = 777,
126                 .vtotal = 806,
127                 .vscan = 0,
128                 .vrefresh = 60,
129                 .flags = 0xA,
130                 .type = 0x40,
131                 .name = "Custom 1024x768",
132         };
133
134         disable_all_screens(drm_fd, drm_res);
135
136         for (i = 0; i < drm_res->count_connectors; i++) {
137                 drmModeConnectorPtr c = drm_connectors[i];
138
139                 if (c->connector_type != DRM_MODE_CONNECTOR_eDP)
140                         continue;
141                 if (c->connection != DRM_MODE_CONNECTED)
142                         continue;
143
144                 if (!use_panel_fitter && c->count_modes) {
145                         connector_id = c->connector_id;
146                         mode = &c->modes[0];
147                         break;
148                 }
149                 if (use_panel_fitter) {
150                         connector_id = c->connector_id;
151
152                         /* This is one of the modes Xorg creates for panels, so
153                          * it should work just fine. Notice that Gens that
154                          * support LPSP are too new for panels with native
155                          * 1024x768 resolution, so this should force the panel
156                          * fitter. */
157                         igt_assert(c->count_modes &&
158                                    c->modes[0].hdisplay > 1024);
159                         igt_assert(c->count_modes &&
160                                    c->modes[0].vdisplay > 768);
161                         mode = &std_1024_mode;
162                         break;
163                 }
164         }
165         igt_require(connector_id);
166
167         crtc_id = drm_res->crtcs[0];
168         buffer_id = create_fb(drm_fd, mode->hdisplay, mode->vdisplay);
169
170         igt_assert(crtc_id);
171         igt_assert(buffer_id);
172         igt_assert(connector_id);
173         igt_assert(mode);
174
175         rc = drmModeSetCrtc(drm_fd, crtc_id, buffer_id, 0, 0, &connector_id, 1,
176                             mode);
177         igt_assert(rc == 0);
178
179         if (use_panel_fitter) {
180                 if (IS_HASWELL(devid))
181                         igt_assert(!lpsp_is_enabled(drm_fd));
182                 else
183                         igt_assert(lpsp_is_enabled(drm_fd));
184         } else {
185                 igt_assert(lpsp_is_enabled(drm_fd));
186         }
187 }
188
189 static void non_edp_subtest(int drm_fd, drmModeResPtr drm_res,
190                             drmModeConnectorPtr *drm_connectors)
191 {
192         int i, rc;
193         uint32_t connector_id = 0, crtc_id = 0, buffer_id = 0;
194         drmModeModeInfoPtr mode = NULL;
195
196         disable_all_screens(drm_fd, drm_res);
197
198         for (i = 0; i < drm_res->count_connectors; i++) {
199                 drmModeConnectorPtr c = drm_connectors[i];
200
201                 if (c->connector_type == DRM_MODE_CONNECTOR_eDP)
202                         continue;
203                 if (c->connection != DRM_MODE_CONNECTED)
204                         continue;
205
206                 if (c->count_modes) {
207                         connector_id = c->connector_id;
208                         mode = &c->modes[0];
209                         break;
210                 }
211         }
212         igt_require(connector_id);
213
214         crtc_id = drm_res->crtcs[0];
215         buffer_id = create_fb(drm_fd, mode->hdisplay, mode->vdisplay);
216
217         igt_assert(crtc_id);
218         igt_assert(buffer_id);
219         igt_assert(connector_id);
220         igt_assert(mode);
221
222         rc = drmModeSetCrtc(drm_fd, crtc_id, buffer_id, 0, 0, &connector_id, 1,
223                             mode);
224         igt_assert(rc == 0);
225
226         igt_assert(!lpsp_is_enabled(drm_fd));
227 }
228
229 #define MAX_CONNECTORS 32
230
231 int drm_fd;
232 uint32_t devid;
233 drmModeResPtr drm_res;
234 drmModeConnectorPtr drm_connectors[MAX_CONNECTORS];
235
236 igt_main
237 {
238         igt_fixture {
239                 int i;
240
241                 drm_fd = drm_open_any();
242                 igt_require(drm_fd >= 0);
243
244                 devid = intel_get_drm_devid(drm_fd);
245
246                 drm_res = drmModeGetResources(drm_fd);
247                 igt_assert(drm_res->count_connectors <= MAX_CONNECTORS);
248
249                 for (i = 0; i < drm_res->count_connectors; i++)
250                         drm_connectors[i] = drmModeGetConnector(drm_fd,
251                                                         drm_res->connectors[i]);
252
253                 disable_audio_runtime_pm();
254
255                 igt_require(supports_lpsp(devid));
256
257                 intel_register_access_init(intel_get_pci_device(), 0);
258
259                 igt_set_vt_graphics_mode();
260         }
261
262         igt_subtest("screens-disabled")
263                 screens_disabled_subtest(drm_fd, drm_res);
264         igt_subtest("edp-native")
265                 edp_subtest(drm_fd, drm_res, drm_connectors, devid, false);
266         igt_subtest("edp-panel-fitter")
267                 edp_subtest(drm_fd, drm_res, drm_connectors, devid, true);
268         igt_subtest("non-edp")
269                 non_edp_subtest(drm_fd, drm_res, drm_connectors);
270
271         igt_fixture {
272                 int i;
273
274                 intel_register_access_fini();
275                 for (i = 0; i < drm_res->count_connectors; i++)
276                         drmModeFreeConnector(drm_connectors[i]);
277                 drmModeFreeResources(drm_res);
278                 close(drm_fd);
279         }
280 }