diff options
author | Dave Airlie <airlied@redhat.com> | 2014-03-18 05:06:53 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-03-18 05:06:53 -0400 |
commit | 8ad2bc9796994ecba9f4ba2fc9abca27ee9d193d (patch) | |
tree | b36c83fa93da7f18c1331252fb82a87431697443 | |
parent | e40d641099213145a034981e646dc2180a488152 (diff) | |
parent | e19b9137142988bec5a76c5f8bdf12a77ea802b0 (diff) |
Merge branch 'drm-intel-next' of git://git.freedesktop.org/git/drm-intel into drm-next
- fine-grained display power domains for byt (Imre)
- runtime pm prep patches for !hsw from Paulo
- WiZ hashing flag updates from Ville
- ppgtt setup cleanup and enabling of full 4G range on bdw (Ben)
- fixes from Jesse for the inherited intial config code
- gpu reset code improvements from Mika
- per-pipe num_planes refactoring from Damien
- stability fixes around bdw forcewake handling and other bdw w/a from Mika
Ken
- and as usual a pile of smaller fixes all over
* 'drm-intel-next' of git://git.freedesktop.org/git/drm-intel: (107 commits)
drm/i915: Go OCD on the Makefile
drm/i915: Implement command buffer parsing logic
drm/i915: Refactor shmem pread setup
drm/i915: Avoid div by zero when pixel clock is large
drm/i915: power domains: add vlv power wells
drm/i915: factor out intel_set_cpu_fifo_underrun_reporting_nolock
drm/i915: vlv: factor out valleyview_display_irq_install
drm/i915: sanity check power well sw state against hw state
drm/i915: factor out reset_vblank_counter
drm/i915: sanitize PUNIT register macro definitions
drm/i915: vlv: keep first level vblank IRQs masked
drm/i915: check pipe power domain when reading its hw state
drm/i915: check port power domain when reading the encoder hw state
drm/i915: get port power domain in connector detect handlers
drm/i915: add port power domains
drm/i915: add noop power well handlers instead of NULL checking them
drm/i915: split power well 'set' handler to separate enable/disable/sync_hw
drm/i915: add init power domain to always-on power wells
drm/i915: move power domain macros to intel_pm.c
drm/i915: Disable full ppgtt by default
...
29 files changed, 2896 insertions, 1019 deletions
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index f33902ff2c22..b1445b73465b 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -3,58 +3,69 @@ | |||
3 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. | 3 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. |
4 | 4 | ||
5 | ccflags-y := -Iinclude/drm | 5 | ccflags-y := -Iinclude/drm |
6 | i915-y := i915_drv.o i915_dma.o i915_irq.o \ | 6 | |
7 | i915_gpu_error.o \ | 7 | # Please keep these build lists sorted! |
8 | |||
9 | # core driver code | ||
10 | i915-y := i915_drv.o \ | ||
11 | i915_params.o \ | ||
8 | i915_suspend.o \ | 12 | i915_suspend.o \ |
9 | i915_gem.o \ | 13 | i915_sysfs.o \ |
14 | intel_pm.o | ||
15 | i915-$(CONFIG_COMPAT) += i915_ioc32.o | ||
16 | i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o | ||
17 | |||
18 | # GEM code | ||
19 | i915-y += i915_cmd_parser.o \ | ||
10 | i915_gem_context.o \ | 20 | i915_gem_context.o \ |
11 | i915_gem_debug.o \ | 21 | i915_gem_debug.o \ |
22 | i915_gem_dmabuf.o \ | ||
12 | i915_gem_evict.o \ | 23 | i915_gem_evict.o \ |
13 | i915_gem_execbuffer.o \ | 24 | i915_gem_execbuffer.o \ |
14 | i915_gem_gtt.o \ | 25 | i915_gem_gtt.o \ |
26 | i915_gem.o \ | ||
15 | i915_gem_stolen.o \ | 27 | i915_gem_stolen.o \ |
16 | i915_gem_tiling.o \ | 28 | i915_gem_tiling.o \ |
17 | i915_params.o \ | 29 | i915_gpu_error.o \ |
18 | i915_sysfs.o \ | 30 | i915_irq.o \ |
19 | i915_trace_points.o \ | 31 | i915_trace_points.o \ |
20 | i915_ums.o \ | 32 | intel_ringbuffer.o \ |
33 | intel_uncore.o | ||
34 | |||
35 | # modesetting core code | ||
36 | i915-y += intel_bios.o \ | ||
21 | intel_display.o \ | 37 | intel_display.o \ |
22 | intel_crt.o \ | ||
23 | intel_lvds.o \ | ||
24 | intel_dsi.o \ | ||
25 | intel_dsi_cmd.o \ | ||
26 | intel_dsi_pll.o \ | ||
27 | intel_bios.o \ | ||
28 | intel_ddi.o \ | ||
29 | intel_dp.o \ | ||
30 | intel_hdmi.o \ | ||
31 | intel_sdvo.o \ | ||
32 | intel_modes.o \ | 38 | intel_modes.o \ |
33 | intel_panel.o \ | ||
34 | intel_pm.o \ | ||
35 | intel_i2c.o \ | ||
36 | intel_tv.o \ | ||
37 | intel_dvo.o \ | ||
38 | intel_ringbuffer.o \ | ||
39 | intel_overlay.o \ | 39 | intel_overlay.o \ |
40 | intel_sprite.o \ | ||
41 | intel_sideband.o \ | 40 | intel_sideband.o \ |
42 | intel_uncore.o \ | 41 | intel_sprite.o |
42 | i915-$(CONFIG_ACPI) += intel_acpi.o intel_opregion.o | ||
43 | i915-$(CONFIG_DRM_I915_FBDEV) += intel_fbdev.o | ||
44 | |||
45 | # modesetting output/encoder code | ||
46 | i915-y += dvo_ch7017.o \ | ||
43 | dvo_ch7xxx.o \ | 47 | dvo_ch7xxx.o \ |
44 | dvo_ch7017.o \ | ||
45 | dvo_ivch.o \ | 48 | dvo_ivch.o \ |
46 | dvo_tfp410.o \ | ||
47 | dvo_sil164.o \ | ||
48 | dvo_ns2501.o \ | 49 | dvo_ns2501.o \ |
49 | i915_gem_dmabuf.o | 50 | dvo_sil164.o \ |
50 | 51 | dvo_tfp410.o \ | |
51 | i915-$(CONFIG_COMPAT) += i915_ioc32.o | 52 | intel_crt.o \ |
52 | 53 | intel_ddi.o \ | |
53 | i915-$(CONFIG_ACPI) += intel_acpi.o intel_opregion.o | 54 | intel_dp.o \ |
54 | 55 | intel_dsi_cmd.o \ | |
55 | i915-$(CONFIG_DRM_I915_FBDEV) += intel_fbdev.o | 56 | intel_dsi.o \ |
57 | intel_dsi_pll.o \ | ||
58 | intel_dvo.o \ | ||
59 | intel_hdmi.o \ | ||
60 | intel_i2c.o \ | ||
61 | intel_lvds.o \ | ||
62 | intel_panel.o \ | ||
63 | intel_sdvo.o \ | ||
64 | intel_tv.o | ||
56 | 65 | ||
57 | i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o | 66 | # legacy horrors |
67 | i915-y += i915_dma.o \ | ||
68 | i915_ums.o | ||
58 | 69 | ||
59 | obj-$(CONFIG_DRM_I915) += i915.o | 70 | obj-$(CONFIG_DRM_I915) += i915.o |
60 | 71 | ||
diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c new file mode 100644 index 000000000000..7a5756e9bb86 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c | |||
@@ -0,0 +1,485 @@ | |||
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 | * Authors: | ||
24 | * Brad Volkin <bradley.d.volkin@intel.com> | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | #include "i915_drv.h" | ||
29 | |||
30 | /** | ||
31 | * DOC: i915 batch buffer command parser | ||
32 | * | ||
33 | * Motivation: | ||
34 | * Certain OpenGL features (e.g. transform feedback, performance monitoring) | ||
35 | * require userspace code to submit batches containing commands such as | ||
36 | * MI_LOAD_REGISTER_IMM to access various registers. Unfortunately, some | ||
37 | * generations of the hardware will noop these commands in "unsecure" batches | ||
38 | * (which includes all userspace batches submitted via i915) even though the | ||
39 | * commands may be safe and represent the intended programming model of the | ||
40 | * device. | ||
41 | * | ||
42 | * The software command parser is similar in operation to the command parsing | ||
43 | * done in hardware for unsecure batches. However, the software parser allows | ||
44 | * some operations that would be noop'd by hardware, if the parser determines | ||
45 | * the operation is safe, and submits the batch as "secure" to prevent hardware | ||
46 | * parsing. | ||
47 | * | ||
48 | * Threats: | ||
49 | * At a high level, the hardware (and software) checks attempt to prevent | ||
50 | * granting userspace undue privileges. There are three categories of privilege. | ||
51 | * | ||
52 | * First, commands which are explicitly defined as privileged or which should | ||
53 | * only be used by the kernel driver. The parser generally rejects such | ||
54 | * commands, though it may allow some from the drm master process. | ||
55 | * | ||
56 | * Second, commands which access registers. To support correct/enhanced | ||
57 | * userspace functionality, particularly certain OpenGL extensions, the parser | ||
58 | * provides a whitelist of registers which userspace may safely access (for both | ||
59 | * normal and drm master processes). | ||
60 | * | ||
61 | * Third, commands which access privileged memory (i.e. GGTT, HWS page, etc). | ||
62 | * The parser always rejects such commands. | ||
63 | * | ||
64 | * The majority of the problematic commands fall in the MI_* range, with only a | ||
65 | * few specific commands on each ring (e.g. PIPE_CONTROL and MI_FLUSH_DW). | ||
66 | * | ||
67 | * Implementation: | ||
68 | * Each ring maintains tables of commands and registers which the parser uses in | ||
69 | * scanning batch buffers submitted to that ring. | ||
70 | * | ||
71 | * Since the set of commands that the parser must check for is significantly | ||
72 | * smaller than the number of commands supported, the parser tables contain only | ||
73 | * those commands required by the parser. This generally works because command | ||
74 | * opcode ranges have standard command length encodings. So for commands that | ||
75 | * the parser does not need to check, it can easily skip them. This is | ||
76 | * implementated via a per-ring length decoding vfunc. | ||
77 | * | ||
78 | * Unfortunately, there are a number of commands that do not follow the standard | ||
79 | * length encoding for their opcode range, primarily amongst the MI_* commands. | ||
80 | * To handle this, the parser provides a way to define explicit "skip" entries | ||
81 | * in the per-ring command tables. | ||
82 | * | ||
83 | * Other command table entries map fairly directly to high level categories | ||
84 | * mentioned above: rejected, master-only, register whitelist. The parser | ||
85 | * implements a number of checks, including the privileged memory checks, via a | ||
86 | * general bitmasking mechanism. | ||
87 | */ | ||
88 | |||
89 | static u32 gen7_render_get_cmd_length_mask(u32 cmd_header) | ||
90 | { | ||
91 | u32 client = (cmd_header & INSTR_CLIENT_MASK) >> INSTR_CLIENT_SHIFT; | ||
92 | u32 subclient = | ||
93 | (cmd_header & INSTR_SUBCLIENT_MASK) >> INSTR_SUBCLIENT_SHIFT; | ||
94 | |||
95 | if (client == INSTR_MI_CLIENT) | ||
96 | return 0x3F; | ||
97 | else if (client == INSTR_RC_CLIENT) { | ||
98 | if (subclient == INSTR_MEDIA_SUBCLIENT) | ||
99 | return 0xFFFF; | ||
100 | else | ||
101 | return 0xFF; | ||
102 | } | ||
103 | |||
104 | DRM_DEBUG_DRIVER("CMD: Abnormal rcs cmd length! 0x%08X\n", cmd_header); | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | static u32 gen7_bsd_get_cmd_length_mask(u32 cmd_header) | ||
109 | { | ||
110 | u32 client = (cmd_header & INSTR_CLIENT_MASK) >> INSTR_CLIENT_SHIFT; | ||
111 | u32 subclient = | ||
112 | (cmd_header & INSTR_SUBCLIENT_MASK) >> INSTR_SUBCLIENT_SHIFT; | ||
113 | |||
114 | if (client == INSTR_MI_CLIENT) | ||
115 | return 0x3F; | ||
116 | else if (client == INSTR_RC_CLIENT) { | ||
117 | if (subclient == INSTR_MEDIA_SUBCLIENT) | ||
118 | return 0xFFF; | ||
119 | else | ||
120 | return 0xFF; | ||
121 | } | ||
122 | |||
123 | DRM_DEBUG_DRIVER("CMD: Abnormal bsd cmd length! 0x%08X\n", cmd_header); | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static u32 gen7_blt_get_cmd_length_mask(u32 cmd_header) | ||
128 | { | ||
129 | u32 client = (cmd_header & INSTR_CLIENT_MASK) >> INSTR_CLIENT_SHIFT; | ||
130 | |||
131 | if (client == INSTR_MI_CLIENT) | ||
132 | return 0x3F; | ||
133 | else if (client == INSTR_BC_CLIENT) | ||
134 | return 0xFF; | ||
135 | |||
136 | DRM_DEBUG_DRIVER("CMD: Abnormal blt cmd length! 0x%08X\n", cmd_header); | ||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static void validate_cmds_sorted(struct intel_ring_buffer *ring) | ||
141 | { | ||
142 | int i; | ||
143 | |||
144 | if (!ring->cmd_tables || ring->cmd_table_count == 0) | ||
145 | return; | ||
146 | |||
147 | for (i = 0; i < ring->cmd_table_count; i++) { | ||
148 | const struct drm_i915_cmd_table *table = &ring->cmd_tables[i]; | ||
149 | u32 previous = 0; | ||
150 | int j; | ||
151 | |||
152 | for (j = 0; j < table->count; j++) { | ||
153 | const struct drm_i915_cmd_descriptor *desc = | ||
154 | &table->table[i]; | ||
155 | u32 curr = desc->cmd.value & desc->cmd.mask; | ||
156 | |||
157 | if (curr < previous) | ||
158 | DRM_ERROR("CMD: table not sorted ring=%d table=%d entry=%d cmd=0x%08X prev=0x%08X\n", | ||
159 | ring->id, i, j, curr, previous); | ||
160 | |||
161 | previous = curr; | ||
162 | } | ||
163 | } | ||
164 | } | ||
165 | |||
166 | static void check_sorted(int ring_id, const u32 *reg_table, int reg_count) | ||
167 | { | ||
168 | int i; | ||
169 | u32 previous = 0; | ||
170 | |||
171 | for (i = 0; i < reg_count; i++) { | ||
172 | u32 curr = reg_table[i]; | ||
173 | |||
174 | if (curr < previous) | ||
175 | DRM_ERROR("CMD: table not sorted ring=%d entry=%d reg=0x%08X prev=0x%08X\n", | ||
176 | ring_id, i, curr, previous); | ||
177 | |||
178 | previous = curr; | ||
179 | } | ||
180 | } | ||
181 | |||
182 | static void validate_regs_sorted(struct intel_ring_buffer *ring) | ||
183 | { | ||
184 | check_sorted(ring->id, ring->reg_table, ring->reg_count); | ||
185 | check_sorted(ring->id, ring->master_reg_table, ring->master_reg_count); | ||
186 | } | ||
187 | |||
188 | /** | ||
189 | * i915_cmd_parser_init_ring() - set cmd parser related fields for a ringbuffer | ||
190 | * @ring: the ringbuffer to initialize | ||
191 | * | ||
192 | * Optionally initializes fields related to batch buffer command parsing in the | ||
193 | * struct intel_ring_buffer based on whether the platform requires software | ||
194 | * command parsing. | ||
195 | */ | ||
196 | void i915_cmd_parser_init_ring(struct intel_ring_buffer *ring) | ||
197 | { | ||
198 | if (!IS_GEN7(ring->dev)) | ||
199 | return; | ||
200 | |||
201 | switch (ring->id) { | ||
202 | case RCS: | ||
203 | ring->get_cmd_length_mask = gen7_render_get_cmd_length_mask; | ||
204 | break; | ||
205 | case VCS: | ||
206 | ring->get_cmd_length_mask = gen7_bsd_get_cmd_length_mask; | ||
207 | break; | ||
208 | case BCS: | ||
209 | ring->get_cmd_length_mask = gen7_blt_get_cmd_length_mask; | ||
210 | break; | ||
211 | case VECS: | ||
212 | /* VECS can use the same length_mask function as VCS */ | ||
213 | ring->get_cmd_length_mask = gen7_bsd_get_cmd_length_mask; | ||
214 | break; | ||
215 | default: | ||
216 | DRM_ERROR("CMD: cmd_parser_init with unknown ring: %d\n", | ||
217 | ring->id); | ||
218 | BUG(); | ||
219 | } | ||
220 | |||
221 | validate_cmds_sorted(ring); | ||
222 | validate_regs_sorted(ring); | ||
223 | } | ||
224 | |||
225 | static const struct drm_i915_cmd_descriptor* | ||
226 | find_cmd_in_table(const struct drm_i915_cmd_table *table, | ||
227 | u32 cmd_header) | ||
228 | { | ||
229 | int i; | ||
230 | |||
231 | for (i = 0; i < table->count; i++) { | ||
232 | const struct drm_i915_cmd_descriptor *desc = &table->table[i]; | ||
233 | u32 masked_cmd = desc->cmd.mask & cmd_header; | ||
234 | u32 masked_value = desc->cmd.value & desc->cmd.mask; | ||
235 | |||
236 | if (masked_cmd == masked_value) | ||
237 | return desc; | ||
238 | } | ||
239 | |||
240 | return NULL; | ||
241 | } | ||
242 | |||
243 | /* | ||
244 | * Returns a pointer to a descriptor for the command specified by cmd_header. | ||
245 | * | ||
246 | * The caller must supply space for a default descriptor via the default_desc | ||
247 | * parameter. If no descriptor for the specified command exists in the ring's | ||
248 | * command parser tables, this function fills in default_desc based on the | ||
249 | * ring's default length encoding and returns default_desc. | ||
250 | */ | ||
251 | static const struct drm_i915_cmd_descriptor* | ||
252 | find_cmd(struct intel_ring_buffer *ring, | ||
253 | u32 cmd_header, | ||
254 | struct drm_i915_cmd_descriptor *default_desc) | ||
255 | { | ||
256 | u32 mask; | ||
257 | int i; | ||
258 | |||
259 | for (i = 0; i < ring->cmd_table_count; i++) { | ||
260 | const struct drm_i915_cmd_descriptor *desc; | ||
261 | |||
262 | desc = find_cmd_in_table(&ring->cmd_tables[i], cmd_header); | ||
263 | if (desc) | ||
264 | return desc; | ||
265 | } | ||
266 | |||
267 | mask = ring->get_cmd_length_mask(cmd_header); | ||
268 | if (!mask) | ||
269 | return NULL; | ||
270 | |||
271 | BUG_ON(!default_desc); | ||
272 | default_desc->flags = CMD_DESC_SKIP; | ||
273 | default_desc->length.mask = mask; | ||
274 | |||
275 | return default_desc; | ||
276 | } | ||
277 | |||
278 | static bool valid_reg(const u32 *table, int count, u32 addr) | ||
279 | { | ||
280 | if (table && count != 0) { | ||
281 | int i; | ||
282 | |||
283 | for (i = 0; i < count; i++) { | ||
284 | if (table[i] == addr) | ||
285 | return true; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | return false; | ||
290 | } | ||
291 | |||
292 | static u32 *vmap_batch(struct drm_i915_gem_object *obj) | ||
293 | { | ||
294 | int i; | ||
295 | void *addr = NULL; | ||
296 | struct sg_page_iter sg_iter; | ||
297 | struct page **pages; | ||
298 | |||
299 | pages = drm_malloc_ab(obj->base.size >> PAGE_SHIFT, sizeof(*pages)); | ||
300 | if (pages == NULL) { | ||
301 | DRM_DEBUG_DRIVER("Failed to get space for pages\n"); | ||
302 | goto finish; | ||
303 | } | ||
304 | |||
305 | i = 0; | ||
306 | for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) { | ||
307 | pages[i] = sg_page_iter_page(&sg_iter); | ||
308 | i++; | ||
309 | } | ||
310 | |||
311 | addr = vmap(pages, i, 0, PAGE_KERNEL); | ||
312 | if (addr == NULL) { | ||
313 | DRM_DEBUG_DRIVER("Failed to vmap pages\n"); | ||
314 | goto finish; | ||
315 | } | ||
316 | |||
317 | finish: | ||
318 | if (pages) | ||
319 | drm_free_large(pages); | ||
320 | return (u32*)addr; | ||
321 | } | ||
322 | |||
323 | /** | ||
324 | * i915_needs_cmd_parser() - should a given ring use software command parsing? | ||
325 | * @ring: the ring in question | ||
326 | * | ||
327 | * Only certain platforms require software batch buffer command parsing, and | ||
328 | * only when enabled via module paramter. | ||
329 | * | ||
330 | * Return: true if the ring requires software command parsing | ||
331 | */ | ||
332 | bool i915_needs_cmd_parser(struct intel_ring_buffer *ring) | ||
333 | { | ||
334 | /* No command tables indicates a platform without parsing */ | ||
335 | if (!ring->cmd_tables) | ||
336 | return false; | ||
337 | |||
338 | return (i915.enable_cmd_parser == 1); | ||
339 | } | ||
340 | |||
341 | #define LENGTH_BIAS 2 | ||
342 | |||
343 | /** | ||
344 | * i915_parse_cmds() - parse a submitted batch buffer for privilege violations | ||
345 | * @ring: the ring on which the batch is to execute | ||
346 | * @batch_obj: the batch buffer in question | ||
347 | * @batch_start_offset: byte offset in the batch at which execution starts | ||
348 | * @is_master: is the submitting process the drm master? | ||
349 | * | ||
350 | * Parses the specified batch buffer looking for privilege violations as | ||
351 | * described in the overview. | ||
352 | * | ||
353 | * Return: non-zero if the parser finds violations or otherwise fails | ||
354 | */ | ||
355 | int i915_parse_cmds(struct intel_ring_buffer *ring, | ||
356 | struct drm_i915_gem_object *batch_obj, | ||
357 | u32 batch_start_offset, | ||
358 | bool is_master) | ||
359 | { | ||
360 | int ret = 0; | ||
361 | u32 *cmd, *batch_base, *batch_end; | ||
362 | struct drm_i915_cmd_descriptor default_desc = { 0 }; | ||
363 | int needs_clflush = 0; | ||
364 | |||
365 | ret = i915_gem_obj_prepare_shmem_read(batch_obj, &needs_clflush); | ||
366 | if (ret) { | ||
367 | DRM_DEBUG_DRIVER("CMD: failed to prep read\n"); | ||
368 | return ret; | ||
369 | } | ||
370 | |||
371 | batch_base = vmap_batch(batch_obj); | ||
372 | if (!batch_base) { | ||
373 | DRM_DEBUG_DRIVER("CMD: Failed to vmap batch\n"); | ||
374 | i915_gem_object_unpin_pages(batch_obj); | ||
375 | return -ENOMEM; | ||
376 | } | ||
377 | |||
378 | if (needs_clflush) | ||
379 | drm_clflush_virt_range((char *)batch_base, batch_obj->base.size); | ||
380 | |||
381 | cmd = batch_base + (batch_start_offset / sizeof(*cmd)); | ||
382 | batch_end = cmd + (batch_obj->base.size / sizeof(*batch_end)); | ||
383 | |||
384 | while (cmd < batch_end) { | ||
385 | const struct drm_i915_cmd_descriptor *desc; | ||
386 | u32 length; | ||
387 | |||
388 | if (*cmd == MI_BATCH_BUFFER_END) | ||
389 | break; | ||
390 | |||
391 | desc = find_cmd(ring, *cmd, &default_desc); | ||
392 | if (!desc) { | ||
393 | DRM_DEBUG_DRIVER("CMD: Unrecognized command: 0x%08X\n", | ||
394 | *cmd); | ||
395 | ret = -EINVAL; | ||
396 | break; | ||
397 | } | ||
398 | |||
399 | if (desc->flags & CMD_DESC_FIXED) | ||
400 | length = desc->length.fixed; | ||
401 | else | ||
402 | length = ((*cmd & desc->length.mask) + LENGTH_BIAS); | ||
403 | |||
404 | if ((batch_end - cmd) < length) { | ||
405 | DRM_DEBUG_DRIVER("CMD: Command length exceeds batch length: 0x%08X length=%d batchlen=%ld\n", | ||
406 | *cmd, | ||
407 | length, | ||
408 | batch_end - cmd); | ||
409 | ret = -EINVAL; | ||
410 | break; | ||
411 | } | ||
412 | |||
413 | if (desc->flags & CMD_DESC_REJECT) { | ||
414 | DRM_DEBUG_DRIVER("CMD: Rejected command: 0x%08X\n", *cmd); | ||
415 | ret = -EINVAL; | ||
416 | break; | ||
417 | } | ||
418 | |||
419 | if ((desc->flags & CMD_DESC_MASTER) && !is_master) { | ||
420 | DRM_DEBUG_DRIVER("CMD: Rejected master-only command: 0x%08X\n", | ||
421 | *cmd); | ||
422 | ret = -EINVAL; | ||
423 | break; | ||
424 | } | ||
425 | |||
426 | if (desc->flags & CMD_DESC_REGISTER) { | ||
427 | u32 reg_addr = cmd[desc->reg.offset] & desc->reg.mask; | ||
428 | |||
429 | if (!valid_reg(ring->reg_table, | ||
430 | ring->reg_count, reg_addr)) { | ||
431 | if (!is_master || | ||
432 | !valid_reg(ring->master_reg_table, | ||
433 | ring->master_reg_count, | ||
434 | reg_addr)) { | ||
435 | DRM_DEBUG_DRIVER("CMD: Rejected register 0x%08X in command: 0x%08X (ring=%d)\n", | ||
436 | reg_addr, | ||
437 | *cmd, | ||
438 | ring->id); | ||
439 | ret = -EINVAL; | ||
440 | break; | ||
441 | } | ||
442 | } | ||
443 | } | ||
444 | |||
445 | if (desc->flags & CMD_DESC_BITMASK) { | ||
446 | int i; | ||
447 | |||
448 | for (i = 0; i < MAX_CMD_DESC_BITMASKS; i++) { | ||
449 | u32 dword; | ||
450 | |||
451 | if (desc->bits[i].mask == 0) | ||
452 | break; | ||
453 | |||
454 | dword = cmd[desc->bits[i].offset] & | ||
455 | desc->bits[i].mask; | ||
456 | |||
457 | if (dword != desc->bits[i].expected) { | ||
458 | DRM_DEBUG_DRIVER("CMD: Rejected command 0x%08X for bitmask 0x%08X (exp=0x%08X act=0x%08X) (ring=%d)\n", | ||
459 | *cmd, | ||
460 | desc->bits[i].mask, | ||
461 | desc->bits[i].expected, | ||
462 | dword, ring->id); | ||
463 | ret = -EINVAL; | ||
464 | break; | ||
465 | } | ||
466 | } | ||
467 | |||
468 | if (ret) | ||
469 | break; | ||
470 | } | ||
471 | |||
472 | cmd += length; | ||
473 | } | ||
474 | |||
475 | if (cmd >= batch_end) { | ||
476 | DRM_DEBUG_DRIVER("CMD: Got to the end of the buffer w/o a BBE cmd!\n"); | ||
477 | ret = -EINVAL; | ||
478 | } | ||
479 | |||
480 | vunmap(batch_base); | ||
481 | |||
482 | i915_gem_object_unpin_pages(batch_obj); | ||
483 | |||
484 | return ret; | ||
485 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index d90a70744d93..a90d31c78643 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -602,7 +602,6 @@ static int i915_interrupt_info(struct seq_file *m, void *data) | |||
602 | intel_runtime_pm_get(dev_priv); | 602 | intel_runtime_pm_get(dev_priv); |
603 | 603 | ||
604 | if (INTEL_INFO(dev)->gen >= 8) { | 604 | if (INTEL_INFO(dev)->gen >= 8) { |
605 | int i; | ||
606 | seq_printf(m, "Master Interrupt Control:\t%08x\n", | 605 | seq_printf(m, "Master Interrupt Control:\t%08x\n", |
607 | I915_READ(GEN8_MASTER_IRQ)); | 606 | I915_READ(GEN8_MASTER_IRQ)); |
608 | 607 | ||
@@ -615,16 +614,16 @@ static int i915_interrupt_info(struct seq_file *m, void *data) | |||
615 | i, I915_READ(GEN8_GT_IER(i))); | 614 | i, I915_READ(GEN8_GT_IER(i))); |
616 | } | 615 | } |
617 | 616 | ||
618 | for_each_pipe(i) { | 617 | for_each_pipe(pipe) { |
619 | seq_printf(m, "Pipe %c IMR:\t%08x\n", | 618 | seq_printf(m, "Pipe %c IMR:\t%08x\n", |
620 | pipe_name(i), | 619 | pipe_name(pipe), |
621 | I915_READ(GEN8_DE_PIPE_IMR(i))); | 620 | I915_READ(GEN8_DE_PIPE_IMR(pipe))); |
622 | seq_printf(m, "Pipe %c IIR:\t%08x\n", | 621 | seq_printf(m, "Pipe %c IIR:\t%08x\n", |
623 | pipe_name(i), | 622 | pipe_name(pipe), |
624 | I915_READ(GEN8_DE_PIPE_IIR(i))); | 623 | I915_READ(GEN8_DE_PIPE_IIR(pipe))); |
625 | seq_printf(m, "Pipe %c IER:\t%08x\n", | 624 | seq_printf(m, "Pipe %c IER:\t%08x\n", |
626 | pipe_name(i), | 625 | pipe_name(pipe), |
627 | I915_READ(GEN8_DE_PIPE_IER(i))); | 626 | I915_READ(GEN8_DE_PIPE_IER(pipe))); |
628 | } | 627 | } |
629 | 628 | ||
630 | seq_printf(m, "Display Engine port interrupt mask:\t%08x\n", | 629 | seq_printf(m, "Display Engine port interrupt mask:\t%08x\n", |
@@ -1348,6 +1347,8 @@ static int i915_fbc_status(struct seq_file *m, void *unused) | |||
1348 | return 0; | 1347 | return 0; |
1349 | } | 1348 | } |
1350 | 1349 | ||
1350 | intel_runtime_pm_get(dev_priv); | ||
1351 | |||
1351 | if (intel_fbc_enabled(dev)) { | 1352 | if (intel_fbc_enabled(dev)) { |
1352 | seq_puts(m, "FBC enabled\n"); | 1353 | seq_puts(m, "FBC enabled\n"); |
1353 | } else { | 1354 | } else { |
@@ -1391,6 +1392,9 @@ static int i915_fbc_status(struct seq_file *m, void *unused) | |||
1391 | } | 1392 | } |
1392 | seq_putc(m, '\n'); | 1393 | seq_putc(m, '\n'); |
1393 | } | 1394 | } |
1395 | |||
1396 | intel_runtime_pm_put(dev_priv); | ||
1397 | |||
1394 | return 0; | 1398 | return 0; |
1395 | } | 1399 | } |
1396 | 1400 | ||
@@ -1405,11 +1409,15 @@ static int i915_ips_status(struct seq_file *m, void *unused) | |||
1405 | return 0; | 1409 | return 0; |
1406 | } | 1410 | } |
1407 | 1411 | ||
1412 | intel_runtime_pm_get(dev_priv); | ||
1413 | |||
1408 | if (IS_BROADWELL(dev) || I915_READ(IPS_CTL) & IPS_ENABLE) | 1414 | if (IS_BROADWELL(dev) || I915_READ(IPS_CTL) & IPS_ENABLE) |
1409 | seq_puts(m, "enabled\n"); | 1415 | seq_puts(m, "enabled\n"); |
1410 | else | 1416 | else |
1411 | seq_puts(m, "disabled\n"); | 1417 | seq_puts(m, "disabled\n"); |
1412 | 1418 | ||
1419 | intel_runtime_pm_put(dev_priv); | ||
1420 | |||
1413 | return 0; | 1421 | return 0; |
1414 | } | 1422 | } |
1415 | 1423 | ||
@@ -1420,6 +1428,8 @@ static int i915_sr_status(struct seq_file *m, void *unused) | |||
1420 | drm_i915_private_t *dev_priv = dev->dev_private; | 1428 | drm_i915_private_t *dev_priv = dev->dev_private; |
1421 | bool sr_enabled = false; | 1429 | bool sr_enabled = false; |
1422 | 1430 | ||
1431 | intel_runtime_pm_get(dev_priv); | ||
1432 | |||
1423 | if (HAS_PCH_SPLIT(dev)) | 1433 | if (HAS_PCH_SPLIT(dev)) |
1424 | sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN; | 1434 | sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN; |
1425 | else if (IS_CRESTLINE(dev) || IS_I945G(dev) || IS_I945GM(dev)) | 1435 | else if (IS_CRESTLINE(dev) || IS_I945G(dev) || IS_I945GM(dev)) |
@@ -1429,6 +1439,8 @@ static int i915_sr_status(struct seq_file *m, void *unused) | |||
1429 | else if (IS_PINEVIEW(dev)) | 1439 | else if (IS_PINEVIEW(dev)) |
1430 | sr_enabled = I915_READ(DSPFW3) & PINEVIEW_SELF_REFRESH_EN; | 1440 | sr_enabled = I915_READ(DSPFW3) & PINEVIEW_SELF_REFRESH_EN; |
1431 | 1441 | ||
1442 | intel_runtime_pm_put(dev_priv); | ||
1443 | |||
1432 | seq_printf(m, "self-refresh: %s\n", | 1444 | seq_printf(m, "self-refresh: %s\n", |
1433 | sr_enabled ? "enabled" : "disabled"); | 1445 | sr_enabled ? "enabled" : "disabled"); |
1434 | 1446 | ||
@@ -1468,7 +1480,7 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused) | |||
1468 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 1480 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
1469 | struct drm_device *dev = node->minor->dev; | 1481 | struct drm_device *dev = node->minor->dev; |
1470 | drm_i915_private_t *dev_priv = dev->dev_private; | 1482 | drm_i915_private_t *dev_priv = dev->dev_private; |
1471 | int ret; | 1483 | int ret = 0; |
1472 | int gpu_freq, ia_freq; | 1484 | int gpu_freq, ia_freq; |
1473 | 1485 | ||
1474 | if (!(IS_GEN6(dev) || IS_GEN7(dev))) { | 1486 | if (!(IS_GEN6(dev) || IS_GEN7(dev))) { |
@@ -1476,12 +1488,13 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused) | |||
1476 | return 0; | 1488 | return 0; |
1477 | } | 1489 | } |
1478 | 1490 | ||
1491 | intel_runtime_pm_get(dev_priv); | ||
1492 | |||
1479 | flush_delayed_work(&dev_priv->rps.delayed_resume_work); | 1493 | flush_delayed_work(&dev_priv->rps.delayed_resume_work); |
1480 | 1494 | ||
1481 | ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); | 1495 | ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); |
1482 | if (ret) | 1496 | if (ret) |
1483 | return ret; | 1497 | goto out; |
1484 | intel_runtime_pm_get(dev_priv); | ||
1485 | 1498 | ||
1486 | seq_puts(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\tEffective Ring freq (MHz)\n"); | 1499 | seq_puts(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\tEffective Ring freq (MHz)\n"); |
1487 | 1500 | ||
@@ -1498,10 +1511,11 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused) | |||
1498 | ((ia_freq >> 8) & 0xff) * 100); | 1511 | ((ia_freq >> 8) & 0xff) * 100); |
1499 | } | 1512 | } |
1500 | 1513 | ||
1501 | intel_runtime_pm_put(dev_priv); | ||
1502 | mutex_unlock(&dev_priv->rps.hw_lock); | 1514 | mutex_unlock(&dev_priv->rps.hw_lock); |
1503 | 1515 | ||
1504 | return 0; | 1516 | out: |
1517 | intel_runtime_pm_put(dev_priv); | ||
1518 | return ret; | ||
1505 | } | 1519 | } |
1506 | 1520 | ||
1507 | static int i915_gfxec(struct seq_file *m, void *unused) | 1521 | static int i915_gfxec(struct seq_file *m, void *unused) |
@@ -1757,7 +1771,7 @@ static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev) | |||
1757 | return; | 1771 | return; |
1758 | 1772 | ||
1759 | seq_printf(m, "Page directories: %d\n", ppgtt->num_pd_pages); | 1773 | seq_printf(m, "Page directories: %d\n", ppgtt->num_pd_pages); |
1760 | seq_printf(m, "Page tables: %d\n", ppgtt->num_pt_pages); | 1774 | seq_printf(m, "Page tables: %d\n", ppgtt->num_pd_entries); |
1761 | for_each_ring(ring, dev_priv, unused) { | 1775 | for_each_ring(ring, dev_priv, unused) { |
1762 | seq_printf(m, "%s\n", ring->name); | 1776 | seq_printf(m, "%s\n", ring->name); |
1763 | for (i = 0; i < 4; i++) { | 1777 | for (i = 0; i < 4; i++) { |
@@ -1972,12 +1986,16 @@ static int i915_energy_uJ(struct seq_file *m, void *data) | |||
1972 | if (INTEL_INFO(dev)->gen < 6) | 1986 | if (INTEL_INFO(dev)->gen < 6) |
1973 | return -ENODEV; | 1987 | return -ENODEV; |
1974 | 1988 | ||
1989 | intel_runtime_pm_get(dev_priv); | ||
1990 | |||
1975 | rdmsrl(MSR_RAPL_POWER_UNIT, power); | 1991 | rdmsrl(MSR_RAPL_POWER_UNIT, power); |
1976 | power = (power & 0x1f00) >> 8; | 1992 | power = (power & 0x1f00) >> 8; |
1977 | units = 1000000 / (1 << power); /* convert to uJ */ | 1993 | units = 1000000 / (1 << power); /* convert to uJ */ |
1978 | power = I915_READ(MCH_SECP_NRG_STTS); | 1994 | power = I915_READ(MCH_SECP_NRG_STTS); |
1979 | power *= units; | 1995 | power *= units; |
1980 | 1996 | ||
1997 | intel_runtime_pm_put(dev_priv); | ||
1998 | |||
1981 | seq_printf(m, "%llu", (long long unsigned)power); | 1999 | seq_printf(m, "%llu", (long long unsigned)power); |
1982 | 2000 | ||
1983 | return 0; | 2001 | return 0; |
@@ -1997,7 +2015,7 @@ static int i915_pc8_status(struct seq_file *m, void *unused) | |||
1997 | mutex_lock(&dev_priv->pc8.lock); | 2015 | mutex_lock(&dev_priv->pc8.lock); |
1998 | seq_printf(m, "Requirements met: %s\n", | 2016 | seq_printf(m, "Requirements met: %s\n", |
1999 | yesno(dev_priv->pc8.requirements_met)); | 2017 | yesno(dev_priv->pc8.requirements_met)); |
2000 | seq_printf(m, "GPU idle: %s\n", yesno(dev_priv->pc8.gpu_idle)); | 2018 | seq_printf(m, "GPU idle: %s\n", yesno(!dev_priv->mm.busy)); |
2001 | seq_printf(m, "Disable count: %d\n", dev_priv->pc8.disable_count); | 2019 | seq_printf(m, "Disable count: %d\n", dev_priv->pc8.disable_count); |
2002 | seq_printf(m, "IRQs disabled: %s\n", | 2020 | seq_printf(m, "IRQs disabled: %s\n", |
2003 | yesno(dev_priv->pc8.irqs_disabled)); | 2021 | yesno(dev_priv->pc8.irqs_disabled)); |
@@ -2030,6 +2048,28 @@ static const char *power_domain_str(enum intel_display_power_domain domain) | |||
2030 | return "TRANSCODER_C"; | 2048 | return "TRANSCODER_C"; |
2031 | case POWER_DOMAIN_TRANSCODER_EDP: | 2049 | case POWER_DOMAIN_TRANSCODER_EDP: |
2032 | return "TRANSCODER_EDP"; | 2050 | return "TRANSCODER_EDP"; |
2051 | case POWER_DOMAIN_PORT_DDI_A_2_LANES: | ||
2052 | return "PORT_DDI_A_2_LANES"; | ||
2053 | case POWER_DOMAIN_PORT_DDI_A_4_LANES: | ||
2054 | return "PORT_DDI_A_4_LANES"; | ||
2055 | case POWER_DOMAIN_PORT_DDI_B_2_LANES: | ||
2056 | return "PORT_DDI_B_2_LANES"; | ||
2057 | case POWER_DOMAIN_PORT_DDI_B_4_LANES: | ||
2058 | return "PORT_DDI_B_4_LANES"; | ||
2059 | case POWER_DOMAIN_PORT_DDI_C_2_LANES: | ||
2060 | return "PORT_DDI_C_2_LANES"; | ||
2061 | case POWER_DOMAIN_PORT_DDI_C_4_LANES: | ||
2062 | return "PORT_DDI_C_4_LANES"; | ||
2063 | case POWER_DOMAIN_PORT_DDI_D_2_LANES: | ||
2064 | return "PORT_DDI_D_2_LANES"; | ||
2065 | case POWER_DOMAIN_PORT_DDI_D_4_LANES: | ||
2066 | return "PORT_DDI_D_4_LANES"; | ||
2067 | case POWER_DOMAIN_PORT_DSI: | ||
2068 | return "PORT_DSI"; | ||
2069 | case POWER_DOMAIN_PORT_CRT: | ||
2070 | return "PORT_CRT"; | ||
2071 | case POWER_DOMAIN_PORT_OTHER: | ||
2072 | return "PORT_OTHER"; | ||
2033 | case POWER_DOMAIN_VGA: | 2073 | case POWER_DOMAIN_VGA: |
2034 | return "VGA"; | 2074 | return "VGA"; |
2035 | case POWER_DOMAIN_AUDIO: | 2075 | case POWER_DOMAIN_AUDIO: |
@@ -2180,6 +2220,7 @@ static void intel_connector_info(struct seq_file *m, | |||
2180 | { | 2220 | { |
2181 | struct intel_connector *intel_connector = to_intel_connector(connector); | 2221 | struct intel_connector *intel_connector = to_intel_connector(connector); |
2182 | struct intel_encoder *intel_encoder = intel_connector->encoder; | 2222 | struct intel_encoder *intel_encoder = intel_connector->encoder; |
2223 | struct drm_display_mode *mode; | ||
2183 | 2224 | ||
2184 | seq_printf(m, "connector %d: type %s, status: %s\n", | 2225 | seq_printf(m, "connector %d: type %s, status: %s\n", |
2185 | connector->base.id, drm_get_connector_name(connector), | 2226 | connector->base.id, drm_get_connector_name(connector), |
@@ -2202,6 +2243,9 @@ static void intel_connector_info(struct seq_file *m, | |||
2202 | else if (intel_encoder->type == INTEL_OUTPUT_LVDS) | 2243 | else if (intel_encoder->type == INTEL_OUTPUT_LVDS) |
2203 | intel_lvds_info(m, intel_connector); | 2244 | intel_lvds_info(m, intel_connector); |
2204 | 2245 | ||
2246 | seq_printf(m, "\tmodes:\n"); | ||
2247 | list_for_each_entry(mode, &connector->modes, head) | ||
2248 | intel_seq_print_mode(m, 2, mode); | ||
2205 | } | 2249 | } |
2206 | 2250 | ||
2207 | static int i915_display_info(struct seq_file *m, void *unused) | 2251 | static int i915_display_info(struct seq_file *m, void *unused) |
@@ -3167,9 +3211,8 @@ i915_wedged_set(void *data, u64 val) | |||
3167 | { | 3211 | { |
3168 | struct drm_device *dev = data; | 3212 | struct drm_device *dev = data; |
3169 | 3213 | ||
3170 | DRM_INFO("Manually setting wedged to %llu\n", val); | 3214 | i915_handle_error(dev, val, |
3171 | i915_handle_error(dev, val); | 3215 | "Manually setting wedged to %llu", val); |
3172 | |||
3173 | return 0; | 3216 | return 0; |
3174 | } | 3217 | } |
3175 | 3218 | ||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 7688abc83fc0..e4d2b9f15ae2 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1321,12 +1321,12 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
1321 | if (ret) | 1321 | if (ret) |
1322 | goto cleanup_vga_switcheroo; | 1322 | goto cleanup_vga_switcheroo; |
1323 | 1323 | ||
1324 | intel_power_domains_init_hw(dev_priv); | ||
1325 | |||
1324 | ret = drm_irq_install(dev); | 1326 | ret = drm_irq_install(dev); |
1325 | if (ret) | 1327 | if (ret) |
1326 | goto cleanup_gem_stolen; | 1328 | goto cleanup_gem_stolen; |
1327 | 1329 | ||
1328 | intel_power_domains_init_hw(dev); | ||
1329 | |||
1330 | /* Important: The output setup functions called by modeset_init need | 1330 | /* Important: The output setup functions called by modeset_init need |
1331 | * working irqs for e.g. gmbus and dp aux transfers. */ | 1331 | * working irqs for e.g. gmbus and dp aux transfers. */ |
1332 | intel_modeset_init(dev); | 1332 | intel_modeset_init(dev); |
@@ -1343,7 +1343,7 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
1343 | /* FIXME: do pre/post-mode set stuff in core KMS code */ | 1343 | /* FIXME: do pre/post-mode set stuff in core KMS code */ |
1344 | dev->vblank_disable_allowed = true; | 1344 | dev->vblank_disable_allowed = true; |
1345 | if (INTEL_INFO(dev)->num_pipes == 0) { | 1345 | if (INTEL_INFO(dev)->num_pipes == 0) { |
1346 | intel_display_power_put(dev, POWER_DOMAIN_VGA); | 1346 | intel_display_power_put(dev_priv, POWER_DOMAIN_VGA); |
1347 | return 0; | 1347 | return 0; |
1348 | } | 1348 | } |
1349 | 1349 | ||
@@ -1381,7 +1381,7 @@ cleanup_gem: | |||
1381 | WARN_ON(dev_priv->mm.aliasing_ppgtt); | 1381 | WARN_ON(dev_priv->mm.aliasing_ppgtt); |
1382 | drm_mm_takedown(&dev_priv->gtt.base.mm); | 1382 | drm_mm_takedown(&dev_priv->gtt.base.mm); |
1383 | cleanup_power: | 1383 | cleanup_power: |
1384 | intel_display_power_put(dev, POWER_DOMAIN_VGA); | 1384 | intel_display_power_put(dev_priv, POWER_DOMAIN_VGA); |
1385 | drm_irq_uninstall(dev); | 1385 | drm_irq_uninstall(dev); |
1386 | cleanup_gem_stolen: | 1386 | cleanup_gem_stolen: |
1387 | i915_gem_cleanup_stolen(dev); | 1387 | i915_gem_cleanup_stolen(dev); |
@@ -1480,12 +1480,16 @@ static void intel_device_info_runtime_init(struct drm_device *dev) | |||
1480 | { | 1480 | { |
1481 | struct drm_i915_private *dev_priv = dev->dev_private; | 1481 | struct drm_i915_private *dev_priv = dev->dev_private; |
1482 | struct intel_device_info *info; | 1482 | struct intel_device_info *info; |
1483 | enum pipe pipe; | ||
1483 | 1484 | ||
1484 | info = (struct intel_device_info *)&dev_priv->info; | 1485 | info = (struct intel_device_info *)&dev_priv->info; |
1485 | 1486 | ||
1486 | info->num_sprites = 1; | ||
1487 | if (IS_VALLEYVIEW(dev)) | 1487 | if (IS_VALLEYVIEW(dev)) |
1488 | info->num_sprites = 2; | 1488 | for_each_pipe(pipe) |
1489 | info->num_sprites[pipe] = 2; | ||
1490 | else | ||
1491 | for_each_pipe(pipe) | ||
1492 | info->num_sprites[pipe] = 1; | ||
1489 | 1493 | ||
1490 | if (i915.disable_display) { | 1494 | if (i915.disable_display) { |
1491 | DRM_INFO("Display disabled (module parameter)\n"); | 1495 | DRM_INFO("Display disabled (module parameter)\n"); |
@@ -1702,7 +1706,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1702 | goto out_gem_unload; | 1706 | goto out_gem_unload; |
1703 | } | 1707 | } |
1704 | 1708 | ||
1705 | intel_power_domains_init(dev); | 1709 | intel_power_domains_init(dev_priv); |
1706 | 1710 | ||
1707 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 1711 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
1708 | ret = i915_load_modeset_init(dev); | 1712 | ret = i915_load_modeset_init(dev); |
@@ -1731,7 +1735,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1731 | return 0; | 1735 | return 0; |
1732 | 1736 | ||
1733 | out_power_well: | 1737 | out_power_well: |
1734 | intel_power_domains_remove(dev); | 1738 | intel_power_domains_remove(dev_priv); |
1735 | drm_vblank_cleanup(dev); | 1739 | drm_vblank_cleanup(dev); |
1736 | out_gem_unload: | 1740 | out_gem_unload: |
1737 | if (dev_priv->mm.inactive_shrinker.scan_objects) | 1741 | if (dev_priv->mm.inactive_shrinker.scan_objects) |
@@ -1781,8 +1785,8 @@ int i915_driver_unload(struct drm_device *dev) | |||
1781 | /* The i915.ko module is still not prepared to be loaded when | 1785 | /* The i915.ko module is still not prepared to be loaded when |
1782 | * the power well is not enabled, so just enable it in case | 1786 | * the power well is not enabled, so just enable it in case |
1783 | * we're going to unload/reload. */ | 1787 | * we're going to unload/reload. */ |
1784 | intel_display_set_init_power(dev, true); | 1788 | intel_display_set_init_power(dev_priv, true); |
1785 | intel_power_domains_remove(dev); | 1789 | intel_power_domains_remove(dev_priv); |
1786 | 1790 | ||
1787 | i915_teardown_sysfs(dev); | 1791 | i915_teardown_sysfs(dev); |
1788 | 1792 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2d05d7ce4c29..6ac91fcdb4f8 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -265,6 +265,7 @@ static const struct intel_device_info intel_broadwell_d_info = { | |||
265 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, | 265 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, |
266 | .has_llc = 1, | 266 | .has_llc = 1, |
267 | .has_ddi = 1, | 267 | .has_ddi = 1, |
268 | .has_fbc = 1, | ||
268 | GEN_DEFAULT_PIPEOFFSETS, | 269 | GEN_DEFAULT_PIPEOFFSETS, |
269 | }; | 270 | }; |
270 | 271 | ||
@@ -274,6 +275,7 @@ static const struct intel_device_info intel_broadwell_m_info = { | |||
274 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, | 275 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, |
275 | .has_llc = 1, | 276 | .has_llc = 1, |
276 | .has_ddi = 1, | 277 | .has_ddi = 1, |
278 | .has_fbc = 1, | ||
277 | GEN_DEFAULT_PIPEOFFSETS, | 279 | GEN_DEFAULT_PIPEOFFSETS, |
278 | }; | 280 | }; |
279 | 281 | ||
@@ -401,15 +403,13 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) | |||
401 | if (INTEL_INFO(dev)->gen < 6) | 403 | if (INTEL_INFO(dev)->gen < 6) |
402 | return false; | 404 | return false; |
403 | 405 | ||
404 | /* Until we get further testing... */ | ||
405 | if (IS_GEN8(dev)) { | ||
406 | WARN_ON(!i915.preliminary_hw_support); | ||
407 | return false; | ||
408 | } | ||
409 | |||
410 | if (i915.semaphores >= 0) | 406 | if (i915.semaphores >= 0) |
411 | return i915.semaphores; | 407 | return i915.semaphores; |
412 | 408 | ||
409 | /* Until we get further testing... */ | ||
410 | if (IS_GEN8(dev)) | ||
411 | return false; | ||
412 | |||
413 | #ifdef CONFIG_INTEL_IOMMU | 413 | #ifdef CONFIG_INTEL_IOMMU |
414 | /* Enable semaphores on SNB when IO remapping is off */ | 414 | /* Enable semaphores on SNB when IO remapping is off */ |
415 | if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) | 415 | if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) |
@@ -434,7 +434,7 @@ static int i915_drm_freeze(struct drm_device *dev) | |||
434 | /* We do a lot of poking in a lot of registers, make sure they work | 434 | /* We do a lot of poking in a lot of registers, make sure they work |
435 | * properly. */ | 435 | * properly. */ |
436 | hsw_disable_package_c8(dev_priv); | 436 | hsw_disable_package_c8(dev_priv); |
437 | intel_display_set_init_power(dev, true); | 437 | intel_display_set_init_power(dev_priv, true); |
438 | 438 | ||
439 | drm_kms_helper_poll_disable(dev); | 439 | drm_kms_helper_poll_disable(dev); |
440 | 440 | ||
@@ -477,6 +477,8 @@ static int i915_drm_freeze(struct drm_device *dev) | |||
477 | intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED); | 477 | intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED); |
478 | console_unlock(); | 478 | console_unlock(); |
479 | 479 | ||
480 | dev_priv->suspend_count++; | ||
481 | |||
480 | return 0; | 482 | return 0; |
481 | } | 483 | } |
482 | 484 | ||
@@ -556,7 +558,7 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings) | |||
556 | mutex_unlock(&dev->struct_mutex); | 558 | mutex_unlock(&dev->struct_mutex); |
557 | } | 559 | } |
558 | 560 | ||
559 | intel_power_domains_init_hw(dev); | 561 | intel_power_domains_init_hw(dev_priv); |
560 | 562 | ||
561 | i915_restore_state(dev); | 563 | i915_restore_state(dev); |
562 | intel_opregion_setup(dev); | 564 | intel_opregion_setup(dev); |
@@ -847,6 +849,7 @@ static int i915_runtime_suspend(struct device *device) | |||
847 | struct drm_i915_private *dev_priv = dev->dev_private; | 849 | struct drm_i915_private *dev_priv = dev->dev_private; |
848 | 850 | ||
849 | WARN_ON(!HAS_RUNTIME_PM(dev)); | 851 | WARN_ON(!HAS_RUNTIME_PM(dev)); |
852 | assert_force_wake_inactive(dev_priv); | ||
850 | 853 | ||
851 | DRM_DEBUG_KMS("Suspending device\n"); | 854 | DRM_DEBUG_KMS("Suspending device\n"); |
852 | 855 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 05cfcc163a72..2a319ba91a71 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -79,7 +79,7 @@ enum plane { | |||
79 | }; | 79 | }; |
80 | #define plane_name(p) ((p) + 'A') | 80 | #define plane_name(p) ((p) + 'A') |
81 | 81 | ||
82 | #define sprite_name(p, s) ((p) * INTEL_INFO(dev)->num_sprites + (s) + 'A') | 82 | #define sprite_name(p, s) ((p) * INTEL_INFO(dev)->num_sprites[(p)] + (s) + 'A') |
83 | 83 | ||
84 | enum port { | 84 | enum port { |
85 | PORT_A = 0, | 85 | PORT_A = 0, |
@@ -114,6 +114,17 @@ enum intel_display_power_domain { | |||
114 | POWER_DOMAIN_TRANSCODER_B, | 114 | POWER_DOMAIN_TRANSCODER_B, |
115 | POWER_DOMAIN_TRANSCODER_C, | 115 | POWER_DOMAIN_TRANSCODER_C, |
116 | POWER_DOMAIN_TRANSCODER_EDP, | 116 | POWER_DOMAIN_TRANSCODER_EDP, |
117 | POWER_DOMAIN_PORT_DDI_A_2_LANES, | ||
118 | POWER_DOMAIN_PORT_DDI_A_4_LANES, | ||
119 | POWER_DOMAIN_PORT_DDI_B_2_LANES, | ||
120 | POWER_DOMAIN_PORT_DDI_B_4_LANES, | ||
121 | POWER_DOMAIN_PORT_DDI_C_2_LANES, | ||
122 | POWER_DOMAIN_PORT_DDI_C_4_LANES, | ||
123 | POWER_DOMAIN_PORT_DDI_D_2_LANES, | ||
124 | POWER_DOMAIN_PORT_DDI_D_4_LANES, | ||
125 | POWER_DOMAIN_PORT_DSI, | ||
126 | POWER_DOMAIN_PORT_CRT, | ||
127 | POWER_DOMAIN_PORT_OTHER, | ||
117 | POWER_DOMAIN_VGA, | 128 | POWER_DOMAIN_VGA, |
118 | POWER_DOMAIN_AUDIO, | 129 | POWER_DOMAIN_AUDIO, |
119 | POWER_DOMAIN_INIT, | 130 | POWER_DOMAIN_INIT, |
@@ -121,8 +132,6 @@ enum intel_display_power_domain { | |||
121 | POWER_DOMAIN_NUM, | 132 | POWER_DOMAIN_NUM, |
122 | }; | 133 | }; |
123 | 134 | ||
124 | #define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1) | ||
125 | |||
126 | #define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A) | 135 | #define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A) |
127 | #define POWER_DOMAIN_PIPE_PANEL_FITTER(pipe) \ | 136 | #define POWER_DOMAIN_PIPE_PANEL_FITTER(pipe) \ |
128 | ((pipe) + POWER_DOMAIN_PIPE_A_PANEL_FITTER) | 137 | ((pipe) + POWER_DOMAIN_PIPE_A_PANEL_FITTER) |
@@ -130,14 +139,6 @@ enum intel_display_power_domain { | |||
130 | ((tran) == TRANSCODER_EDP ? POWER_DOMAIN_TRANSCODER_EDP : \ | 139 | ((tran) == TRANSCODER_EDP ? POWER_DOMAIN_TRANSCODER_EDP : \ |
131 | (tran) + POWER_DOMAIN_TRANSCODER_A) | 140 | (tran) + POWER_DOMAIN_TRANSCODER_A) |
132 | 141 | ||
133 | #define HSW_ALWAYS_ON_POWER_DOMAINS ( \ | ||
134 | BIT(POWER_DOMAIN_PIPE_A) | \ | ||
135 | BIT(POWER_DOMAIN_TRANSCODER_EDP)) | ||
136 | #define BDW_ALWAYS_ON_POWER_DOMAINS ( \ | ||
137 | BIT(POWER_DOMAIN_PIPE_A) | \ | ||
138 | BIT(POWER_DOMAIN_TRANSCODER_EDP) | \ | ||
139 | BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER)) | ||
140 | |||
141 | enum hpd_pin { | 142 | enum hpd_pin { |
142 | HPD_NONE = 0, | 143 | HPD_NONE = 0, |
143 | HPD_PORT_A = HPD_NONE, /* PORT_A is internal */ | 144 | HPD_PORT_A = HPD_NONE, /* PORT_A is internal */ |
@@ -159,6 +160,7 @@ enum hpd_pin { | |||
159 | I915_GEM_DOMAIN_VERTEX) | 160 | I915_GEM_DOMAIN_VERTEX) |
160 | 161 | ||
161 | #define for_each_pipe(p) for ((p) = 0; (p) < INTEL_INFO(dev)->num_pipes; (p)++) | 162 | #define for_each_pipe(p) for ((p) = 0; (p) < INTEL_INFO(dev)->num_pipes; (p)++) |
163 | #define for_each_sprite(p, s) for ((s) = 0; (s) < INTEL_INFO(dev)->num_sprites[(p)]; (s)++) | ||
162 | 164 | ||
163 | #define for_each_encoder_on_crtc(dev, __crtc, intel_encoder) \ | 165 | #define for_each_encoder_on_crtc(dev, __crtc, intel_encoder) \ |
164 | list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \ | 166 | list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \ |
@@ -303,6 +305,10 @@ struct drm_i915_error_state { | |||
303 | struct kref ref; | 305 | struct kref ref; |
304 | struct timeval time; | 306 | struct timeval time; |
305 | 307 | ||
308 | char error_msg[128]; | ||
309 | u32 reset_count; | ||
310 | u32 suspend_count; | ||
311 | |||
306 | /* Generic register state */ | 312 | /* Generic register state */ |
307 | u32 eir; | 313 | u32 eir; |
308 | u32 pgtbl_er; | 314 | u32 pgtbl_er; |
@@ -360,7 +366,7 @@ struct drm_i915_error_state { | |||
360 | int page_count; | 366 | int page_count; |
361 | u32 gtt_offset; | 367 | u32 gtt_offset; |
362 | u32 *pages[0]; | 368 | u32 *pages[0]; |
363 | } *ringbuffer, *batchbuffer, *ctx, *hws_page; | 369 | } *ringbuffer, *batchbuffer, *wa_batchbuffer, *ctx, *hws_page; |
364 | 370 | ||
365 | struct drm_i915_error_request { | 371 | struct drm_i915_error_request { |
366 | long jiffies; | 372 | long jiffies; |
@@ -375,6 +381,9 @@ struct drm_i915_error_state { | |||
375 | u32 pp_dir_base; | 381 | u32 pp_dir_base; |
376 | }; | 382 | }; |
377 | } vm_info; | 383 | } vm_info; |
384 | |||
385 | pid_t pid; | ||
386 | char comm[TASK_COMM_LEN]; | ||
378 | } ring[I915_NUM_RINGS]; | 387 | } ring[I915_NUM_RINGS]; |
379 | struct drm_i915_error_buffer { | 388 | struct drm_i915_error_buffer { |
380 | u32 size; | 389 | u32 size; |
@@ -499,7 +508,7 @@ struct intel_uncore { | |||
499 | unsigned fw_rendercount; | 508 | unsigned fw_rendercount; |
500 | unsigned fw_mediacount; | 509 | unsigned fw_mediacount; |
501 | 510 | ||
502 | struct delayed_work force_wake_work; | 511 | struct timer_list force_wake_timer; |
503 | }; | 512 | }; |
504 | 513 | ||
505 | #define DEV_INFO_FOR_EACH_FLAG(func, sep) \ | 514 | #define DEV_INFO_FOR_EACH_FLAG(func, sep) \ |
@@ -534,7 +543,7 @@ struct intel_uncore { | |||
534 | struct intel_device_info { | 543 | struct intel_device_info { |
535 | u32 display_mmio_offset; | 544 | u32 display_mmio_offset; |
536 | u8 num_pipes:3; | 545 | u8 num_pipes:3; |
537 | u8 num_sprites:2; | 546 | u8 num_sprites[I915_MAX_PIPES]; |
538 | u8 gen; | 547 | u8 gen; |
539 | u8 ring_mask; /* Rings supported by the HW */ | 548 | u8 ring_mask; /* Rings supported by the HW */ |
540 | DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG, SEP_SEMICOLON); | 549 | DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG, SEP_SEMICOLON); |
@@ -652,12 +661,12 @@ struct i915_address_space { | |||
652 | enum i915_cache_level level, | 661 | enum i915_cache_level level, |
653 | bool valid); /* Create a valid PTE */ | 662 | bool valid); /* Create a valid PTE */ |
654 | void (*clear_range)(struct i915_address_space *vm, | 663 | void (*clear_range)(struct i915_address_space *vm, |
655 | unsigned int first_entry, | 664 | uint64_t start, |
656 | unsigned int num_entries, | 665 | uint64_t length, |
657 | bool use_scratch); | 666 | bool use_scratch); |
658 | void (*insert_entries)(struct i915_address_space *vm, | 667 | void (*insert_entries)(struct i915_address_space *vm, |
659 | struct sg_table *st, | 668 | struct sg_table *st, |
660 | unsigned int first_entry, | 669 | uint64_t start, |
661 | enum i915_cache_level cache_level); | 670 | enum i915_cache_level cache_level); |
662 | void (*cleanup)(struct i915_address_space *vm); | 671 | void (*cleanup)(struct i915_address_space *vm); |
663 | }; | 672 | }; |
@@ -691,21 +700,21 @@ struct i915_gtt { | |||
691 | }; | 700 | }; |
692 | #define gtt_total_entries(gtt) ((gtt).base.total >> PAGE_SHIFT) | 701 | #define gtt_total_entries(gtt) ((gtt).base.total >> PAGE_SHIFT) |
693 | 702 | ||
703 | #define GEN8_LEGACY_PDPS 4 | ||
694 | struct i915_hw_ppgtt { | 704 | struct i915_hw_ppgtt { |
695 | struct i915_address_space base; | 705 | struct i915_address_space base; |
696 | struct kref ref; | 706 | struct kref ref; |
697 | struct drm_mm_node node; | 707 | struct drm_mm_node node; |
698 | unsigned num_pd_entries; | 708 | unsigned num_pd_entries; |
709 | unsigned num_pd_pages; /* gen8+ */ | ||
699 | union { | 710 | union { |
700 | struct page **pt_pages; | 711 | struct page **pt_pages; |
701 | struct page *gen8_pt_pages; | 712 | struct page **gen8_pt_pages[GEN8_LEGACY_PDPS]; |
702 | }; | 713 | }; |
703 | struct page *pd_pages; | 714 | struct page *pd_pages; |
704 | int num_pd_pages; | ||
705 | int num_pt_pages; | ||
706 | union { | 715 | union { |
707 | uint32_t pd_offset; | 716 | uint32_t pd_offset; |
708 | dma_addr_t pd_dma_addr[4]; | 717 | dma_addr_t pd_dma_addr[GEN8_LEGACY_PDPS]; |
709 | }; | 718 | }; |
710 | union { | 719 | union { |
711 | dma_addr_t *pt_dma_addr; | 720 | dma_addr_t *pt_dma_addr; |
@@ -1016,6 +1025,36 @@ struct intel_ilk_power_mgmt { | |||
1016 | struct drm_i915_gem_object *renderctx; | 1025 | struct drm_i915_gem_object *renderctx; |
1017 | }; | 1026 | }; |
1018 | 1027 | ||
1028 | struct drm_i915_private; | ||
1029 | struct i915_power_well; | ||
1030 | |||
1031 | struct i915_power_well_ops { | ||
1032 | /* | ||
1033 | * Synchronize the well's hw state to match the current sw state, for | ||
1034 | * example enable/disable it based on the current refcount. Called | ||
1035 | * during driver init and resume time, possibly after first calling | ||
1036 | * the enable/disable handlers. | ||
1037 | */ | ||
1038 | void (*sync_hw)(struct drm_i915_private *dev_priv, | ||
1039 | struct i915_power_well *power_well); | ||
1040 | /* | ||
1041 | * Enable the well and resources that depend on it (for example | ||
1042 | * interrupts located on the well). Called after the 0->1 refcount | ||
1043 | * transition. | ||
1044 | */ | ||
1045 | void (*enable)(struct drm_i915_private *dev_priv, | ||
1046 | struct i915_power_well *power_well); | ||
1047 | /* | ||
1048 | * Disable the well and resources that depend on it. Called after | ||
1049 | * the 1->0 refcount transition. | ||
1050 | */ | ||
1051 | void (*disable)(struct drm_i915_private *dev_priv, | ||
1052 | struct i915_power_well *power_well); | ||
1053 | /* Returns the hw enabled state. */ | ||
1054 | bool (*is_enabled)(struct drm_i915_private *dev_priv, | ||
1055 | struct i915_power_well *power_well); | ||
1056 | }; | ||
1057 | |||
1019 | /* Power well structure for haswell */ | 1058 | /* Power well structure for haswell */ |
1020 | struct i915_power_well { | 1059 | struct i915_power_well { |
1021 | const char *name; | 1060 | const char *name; |
@@ -1023,11 +1062,8 @@ struct i915_power_well { | |||
1023 | /* power well enable/disable usage count */ | 1062 | /* power well enable/disable usage count */ |
1024 | int count; | 1063 | int count; |
1025 | unsigned long domains; | 1064 | unsigned long domains; |
1026 | void *data; | 1065 | unsigned long data; |
1027 | void (*set)(struct drm_device *dev, struct i915_power_well *power_well, | 1066 | const struct i915_power_well_ops *ops; |
1028 | bool enable); | ||
1029 | bool (*is_enabled)(struct drm_device *dev, | ||
1030 | struct i915_power_well *power_well); | ||
1031 | }; | 1067 | }; |
1032 | 1068 | ||
1033 | struct i915_power_domains { | 1069 | struct i915_power_domains { |
@@ -1124,6 +1160,14 @@ struct i915_gem_mm { | |||
1124 | */ | 1160 | */ |
1125 | bool interruptible; | 1161 | bool interruptible; |
1126 | 1162 | ||
1163 | /** | ||
1164 | * Is the GPU currently considered idle, or busy executing userspace | ||
1165 | * requests? Whilst idle, we attempt to power down the hardware and | ||
1166 | * display clocks. In order to reduce the effect on performance, there | ||
1167 | * is a slight delay before we do so. | ||
1168 | */ | ||
1169 | bool busy; | ||
1170 | |||
1127 | /** Bit 6 swizzling required for X tiling */ | 1171 | /** Bit 6 swizzling required for X tiling */ |
1128 | uint32_t bit_6_swizzle_x; | 1172 | uint32_t bit_6_swizzle_x; |
1129 | /** Bit 6 swizzling required for Y tiling */ | 1173 | /** Bit 6 swizzling required for Y tiling */ |
@@ -1313,11 +1357,10 @@ struct ilk_wm_values { | |||
1313 | * Ideally every piece of our code that needs PC8+ disabled would call | 1357 | * Ideally every piece of our code that needs PC8+ disabled would call |
1314 | * hsw_disable_package_c8, which would increment disable_count and prevent the | 1358 | * hsw_disable_package_c8, which would increment disable_count and prevent the |
1315 | * system from reaching PC8+. But we don't have a symmetric way to do this for | 1359 | * system from reaching PC8+. But we don't have a symmetric way to do this for |
1316 | * everything, so we have the requirements_met and gpu_idle variables. When we | 1360 | * everything, so we have the requirements_met variable. When we switch |
1317 | * switch requirements_met or gpu_idle to true we decrease disable_count, and | 1361 | * requirements_met to true we decrease disable_count, and increase it in the |
1318 | * increase it in the opposite case. The requirements_met variable is true when | 1362 | * opposite case. The requirements_met variable is true when all the CRTCs, |
1319 | * all the CRTCs, encoders and the power well are disabled. The gpu_idle | 1363 | * encoders and the power well are disabled. |
1320 | * variable is true when the GPU is idle. | ||
1321 | * | 1364 | * |
1322 | * In addition to everything, we only actually enable PC8+ if disable_count | 1365 | * In addition to everything, we only actually enable PC8+ if disable_count |
1323 | * stays at zero for at least some seconds. This is implemented with the | 1366 | * stays at zero for at least some seconds. This is implemented with the |
@@ -1340,7 +1383,6 @@ struct ilk_wm_values { | |||
1340 | */ | 1383 | */ |
1341 | struct i915_package_c8 { | 1384 | struct i915_package_c8 { |
1342 | bool requirements_met; | 1385 | bool requirements_met; |
1343 | bool gpu_idle; | ||
1344 | bool irqs_disabled; | 1386 | bool irqs_disabled; |
1345 | /* Only true after the delayed work task actually enables it. */ | 1387 | /* Only true after the delayed work task actually enables it. */ |
1346 | bool enabled; | 1388 | bool enabled; |
@@ -1427,6 +1469,8 @@ typedef struct drm_i915_private { | |||
1427 | /* protects the irq masks */ | 1469 | /* protects the irq masks */ |
1428 | spinlock_t irq_lock; | 1470 | spinlock_t irq_lock; |
1429 | 1471 | ||
1472 | bool display_irqs_enabled; | ||
1473 | |||
1430 | /* To control wakeup latency, e.g. for irq-driven dp aux transfers. */ | 1474 | /* To control wakeup latency, e.g. for irq-driven dp aux transfers. */ |
1431 | struct pm_qos_request pm_qos; | 1475 | struct pm_qos_request pm_qos; |
1432 | 1476 | ||
@@ -1594,6 +1638,8 @@ typedef struct drm_i915_private { | |||
1594 | struct i915_dri1_state dri1; | 1638 | struct i915_dri1_state dri1; |
1595 | /* Old ums support infrastructure, same warning applies. */ | 1639 | /* Old ums support infrastructure, same warning applies. */ |
1596 | struct i915_ums_state ums; | 1640 | struct i915_ums_state ums; |
1641 | |||
1642 | u32 suspend_count; | ||
1597 | } drm_i915_private_t; | 1643 | } drm_i915_private_t; |
1598 | 1644 | ||
1599 | static inline struct drm_i915_private *to_i915(const struct drm_device *dev) | 1645 | static inline struct drm_i915_private *to_i915(const struct drm_device *dev) |
@@ -1745,7 +1791,6 @@ struct drm_i915_gem_object { | |||
1745 | /** for phy allocated objects */ | 1791 | /** for phy allocated objects */ |
1746 | struct drm_i915_gem_phys_object *phys_obj; | 1792 | struct drm_i915_gem_phys_object *phys_obj; |
1747 | }; | 1793 | }; |
1748 | #define to_gem_object(obj) (&((struct drm_i915_gem_object *)(obj))->base) | ||
1749 | 1794 | ||
1750 | #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) | 1795 | #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) |
1751 | 1796 | ||
@@ -1791,6 +1836,7 @@ struct drm_i915_gem_request { | |||
1791 | 1836 | ||
1792 | struct drm_i915_file_private { | 1837 | struct drm_i915_file_private { |
1793 | struct drm_i915_private *dev_priv; | 1838 | struct drm_i915_private *dev_priv; |
1839 | struct drm_file *file; | ||
1794 | 1840 | ||
1795 | struct { | 1841 | struct { |
1796 | spinlock_t lock; | 1842 | spinlock_t lock; |
@@ -1803,6 +1849,90 @@ struct drm_i915_file_private { | |||
1803 | atomic_t rps_wait_boost; | 1849 | atomic_t rps_wait_boost; |
1804 | }; | 1850 | }; |
1805 | 1851 | ||
1852 | /* | ||
1853 | * A command that requires special handling by the command parser. | ||
1854 | */ | ||
1855 | struct drm_i915_cmd_descriptor { | ||
1856 | /* | ||
1857 | * Flags describing how the command parser processes the command. | ||
1858 | * | ||
1859 | * CMD_DESC_FIXED: The command has a fixed length if this is set, | ||
1860 | * a length mask if not set | ||
1861 | * CMD_DESC_SKIP: The command is allowed but does not follow the | ||
1862 | * standard length encoding for the opcode range in | ||
1863 | * which it falls | ||
1864 | * CMD_DESC_REJECT: The command is never allowed | ||
1865 | * CMD_DESC_REGISTER: The command should be checked against the | ||
1866 | * register whitelist for the appropriate ring | ||
1867 | * CMD_DESC_MASTER: The command is allowed if the submitting process | ||
1868 | * is the DRM master | ||
1869 | */ | ||
1870 | u32 flags; | ||
1871 | #define CMD_DESC_FIXED (1<<0) | ||
1872 | #define CMD_DESC_SKIP (1<<1) | ||
1873 | #define CMD_DESC_REJECT (1<<2) | ||
1874 | #define CMD_DESC_REGISTER (1<<3) | ||
1875 | #define CMD_DESC_BITMASK (1<<4) | ||
1876 | #define CMD_DESC_MASTER (1<<5) | ||
1877 | |||
1878 | /* | ||
1879 | * The command's unique identification bits and the bitmask to get them. | ||
1880 | * This isn't strictly the opcode field as defined in the spec and may | ||
1881 | * also include type, subtype, and/or subop fields. | ||
1882 | */ | ||
1883 | struct { | ||
1884 | u32 value; | ||
1885 | u32 mask; | ||
1886 | } cmd; | ||
1887 | |||
1888 | /* | ||
1889 | * The command's length. The command is either fixed length (i.e. does | ||
1890 | * not include a length field) or has a length field mask. The flag | ||
1891 | * CMD_DESC_FIXED indicates a fixed length. Otherwise, the command has | ||
1892 | * a length mask. All command entries in a command table must include | ||
1893 | * length information. | ||
1894 | */ | ||
1895 | union { | ||
1896 | u32 fixed; | ||
1897 | u32 mask; | ||
1898 | } length; | ||
1899 | |||
1900 | /* | ||
1901 | * Describes where to find a register address in the command to check | ||
1902 | * against the ring's register whitelist. Only valid if flags has the | ||
1903 | * CMD_DESC_REGISTER bit set. | ||
1904 | */ | ||
1905 | struct { | ||
1906 | u32 offset; | ||
1907 | u32 mask; | ||
1908 | } reg; | ||
1909 | |||
1910 | #define MAX_CMD_DESC_BITMASKS 3 | ||
1911 | /* | ||
1912 | * Describes command checks where a particular dword is masked and | ||
1913 | * compared against an expected value. If the command does not match | ||
1914 | * the expected value, the parser rejects it. Only valid if flags has | ||
1915 | * the CMD_DESC_BITMASK bit set. Only entries where mask is non-zero | ||
1916 | * are valid. | ||
1917 | */ | ||
1918 | struct { | ||
1919 | u32 offset; | ||
1920 | u32 mask; | ||
1921 | u32 expected; | ||
1922 | } bits[MAX_CMD_DESC_BITMASKS]; | ||
1923 | }; | ||
1924 | |||
1925 | /* | ||
1926 | * A table of commands requiring special handling by the command parser. | ||
1927 | * | ||
1928 | * Each ring has an array of tables. Each table consists of an array of command | ||
1929 | * descriptors, which must be sorted with command opcodes in ascending order. | ||
1930 | */ | ||
1931 | struct drm_i915_cmd_table { | ||
1932 | const struct drm_i915_cmd_descriptor *table; | ||
1933 | int count; | ||
1934 | }; | ||
1935 | |||
1806 | #define INTEL_INFO(dev) (&to_i915(dev)->info) | 1936 | #define INTEL_INFO(dev) (&to_i915(dev)->info) |
1807 | 1937 | ||
1808 | #define IS_I830(dev) ((dev)->pdev->device == 0x3577) | 1938 | #define IS_I830(dev) ((dev)->pdev->device == 0x3577) |
@@ -1965,6 +2095,7 @@ struct i915_params { | |||
1965 | int enable_pc8; | 2095 | int enable_pc8; |
1966 | int pc8_timeout; | 2096 | int pc8_timeout; |
1967 | int invert_brightness; | 2097 | int invert_brightness; |
2098 | int enable_cmd_parser; | ||
1968 | /* leave bools at the end to not create holes */ | 2099 | /* leave bools at the end to not create holes */ |
1969 | bool enable_hangcheck; | 2100 | bool enable_hangcheck; |
1970 | bool fastboot; | 2101 | bool fastboot; |
@@ -2004,7 +2135,9 @@ extern void intel_console_resume(struct work_struct *work); | |||
2004 | 2135 | ||
2005 | /* i915_irq.c */ | 2136 | /* i915_irq.c */ |
2006 | void i915_queue_hangcheck(struct drm_device *dev); | 2137 | void i915_queue_hangcheck(struct drm_device *dev); |
2007 | void i915_handle_error(struct drm_device *dev, bool wedged); | 2138 | __printf(3, 4) |
2139 | void i915_handle_error(struct drm_device *dev, bool wedged, | ||
2140 | const char *fmt, ...); | ||
2008 | 2141 | ||
2009 | void gen6_set_pm_mask(struct drm_i915_private *dev_priv, u32 pm_iir, | 2142 | void gen6_set_pm_mask(struct drm_i915_private *dev_priv, u32 pm_iir, |
2010 | int new_delay); | 2143 | int new_delay); |
@@ -2025,6 +2158,9 @@ void | |||
2025 | i915_disable_pipestat(drm_i915_private_t *dev_priv, enum pipe pipe, | 2158 | i915_disable_pipestat(drm_i915_private_t *dev_priv, enum pipe pipe, |
2026 | u32 status_mask); | 2159 | u32 status_mask); |
2027 | 2160 | ||
2161 | void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv); | ||
2162 | void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv); | ||
2163 | |||
2028 | /* i915_gem.c */ | 2164 | /* i915_gem.c */ |
2029 | int i915_gem_init_ioctl(struct drm_device *dev, void *data, | 2165 | int i915_gem_init_ioctl(struct drm_device *dev, void *data, |
2030 | struct drm_file *file_priv); | 2166 | struct drm_file *file_priv); |
@@ -2097,6 +2233,9 @@ void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv); | |||
2097 | void i915_gem_release_mmap(struct drm_i915_gem_object *obj); | 2233 | void i915_gem_release_mmap(struct drm_i915_gem_object *obj); |
2098 | void i915_gem_lastclose(struct drm_device *dev); | 2234 | void i915_gem_lastclose(struct drm_device *dev); |
2099 | 2235 | ||
2236 | int i915_gem_obj_prepare_shmem_read(struct drm_i915_gem_object *obj, | ||
2237 | int *needs_clflush); | ||
2238 | |||
2100 | int __must_check i915_gem_object_get_pages(struct drm_i915_gem_object *obj); | 2239 | int __must_check i915_gem_object_get_pages(struct drm_i915_gem_object *obj); |
2101 | static inline struct page *i915_gem_object_get_page(struct drm_i915_gem_object *obj, int n) | 2240 | static inline struct page *i915_gem_object_get_page(struct drm_i915_gem_object *obj, int n) |
2102 | { | 2241 | { |
@@ -2163,8 +2302,10 @@ i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj) | |||
2163 | } | 2302 | } |
2164 | } | 2303 | } |
2165 | 2304 | ||
2305 | struct drm_i915_gem_request * | ||
2306 | i915_gem_find_active_request(struct intel_ring_buffer *ring); | ||
2307 | |||
2166 | bool i915_gem_retire_requests(struct drm_device *dev); | 2308 | bool i915_gem_retire_requests(struct drm_device *dev); |
2167 | void i915_gem_retire_requests_ring(struct intel_ring_buffer *ring); | ||
2168 | int __must_check i915_gem_check_wedge(struct i915_gpu_error *error, | 2309 | int __must_check i915_gem_check_wedge(struct i915_gpu_error *error, |
2169 | bool interruptible); | 2310 | bool interruptible); |
2170 | static inline bool i915_reset_in_progress(struct i915_gpu_error *error) | 2311 | static inline bool i915_reset_in_progress(struct i915_gpu_error *error) |
@@ -2365,63 +2506,7 @@ static inline void i915_gem_chipset_flush(struct drm_device *dev) | |||
2365 | intel_gtt_chipset_flush(); | 2506 | intel_gtt_chipset_flush(); |
2366 | } | 2507 | } |
2367 | int i915_gem_init_ppgtt(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt); | 2508 | int i915_gem_init_ppgtt(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt); |
2368 | static inline bool intel_enable_ppgtt(struct drm_device *dev, bool full) | 2509 | bool intel_enable_ppgtt(struct drm_device *dev, bool full); |
2369 | { | ||
2370 | if (i915.enable_ppgtt == 0 || !HAS_ALIASING_PPGTT(dev)) | ||
2371 | return false; | ||
2372 | |||
2373 | if (i915.enable_ppgtt == 1 && full) | ||
2374 | return false; | ||
2375 | |||
2376 | #ifdef CONFIG_INTEL_IOMMU | ||
2377 | /* Disable ppgtt on SNB if VT-d is on. */ | ||
2378 | if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) { | ||
2379 | DRM_INFO("Disabling PPGTT because VT-d is on\n"); | ||
2380 | return false; | ||
2381 | } | ||
2382 | #endif | ||
2383 | |||
2384 | if (full) | ||
2385 | return HAS_PPGTT(dev); | ||
2386 | else | ||
2387 | return HAS_ALIASING_PPGTT(dev); | ||
2388 | } | ||
2389 | |||
2390 | static inline void ppgtt_release(struct kref *kref) | ||
2391 | { | ||
2392 | struct i915_hw_ppgtt *ppgtt = container_of(kref, struct i915_hw_ppgtt, ref); | ||
2393 | struct drm_device *dev = ppgtt->base.dev; | ||
2394 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2395 | struct i915_address_space *vm = &ppgtt->base; | ||
2396 | |||
2397 | if (ppgtt == dev_priv->mm.aliasing_ppgtt || | ||
2398 | (list_empty(&vm->active_list) && list_empty(&vm->inactive_list))) { | ||
2399 | ppgtt->base.cleanup(&ppgtt->base); | ||
2400 | return; | ||
2401 | } | ||
2402 | |||
2403 | /* | ||
2404 | * Make sure vmas are unbound before we take down the drm_mm | ||
2405 | * | ||
2406 | * FIXME: Proper refcounting should take care of this, this shouldn't be | ||
2407 | * needed at all. | ||
2408 | */ | ||
2409 | if (!list_empty(&vm->active_list)) { | ||
2410 | struct i915_vma *vma; | ||
2411 | |||
2412 | list_for_each_entry(vma, &vm->active_list, mm_list) | ||
2413 | if (WARN_ON(list_empty(&vma->vma_link) || | ||
2414 | list_is_singular(&vma->vma_link))) | ||
2415 | break; | ||
2416 | |||
2417 | i915_gem_evict_vm(&ppgtt->base, true); | ||
2418 | } else { | ||
2419 | i915_gem_retire_requests(dev); | ||
2420 | i915_gem_evict_vm(&ppgtt->base, false); | ||
2421 | } | ||
2422 | |||
2423 | ppgtt->base.cleanup(&ppgtt->base); | ||
2424 | } | ||
2425 | 2510 | ||
2426 | /* i915_gem_stolen.c */ | 2511 | /* i915_gem_stolen.c */ |
2427 | int i915_gem_init_stolen(struct drm_device *dev); | 2512 | int i915_gem_init_stolen(struct drm_device *dev); |
@@ -2478,7 +2563,8 @@ static inline void i915_error_state_buf_release( | |||
2478 | { | 2563 | { |
2479 | kfree(eb->buf); | 2564 | kfree(eb->buf); |
2480 | } | 2565 | } |
2481 | void i915_capture_error_state(struct drm_device *dev); | 2566 | void i915_capture_error_state(struct drm_device *dev, bool wedge, |
2567 | const char *error_msg); | ||
2482 | void i915_error_state_get(struct drm_device *dev, | 2568 | void i915_error_state_get(struct drm_device *dev, |
2483 | struct i915_error_state_file_priv *error_priv); | 2569 | struct i915_error_state_file_priv *error_priv); |
2484 | void i915_error_state_put(struct i915_error_state_file_priv *error_priv); | 2570 | void i915_error_state_put(struct i915_error_state_file_priv *error_priv); |
@@ -2487,6 +2573,14 @@ void i915_destroy_error_state(struct drm_device *dev); | |||
2487 | void i915_get_extra_instdone(struct drm_device *dev, uint32_t *instdone); | 2573 | void i915_get_extra_instdone(struct drm_device *dev, uint32_t *instdone); |
2488 | const char *i915_cache_level_str(int type); | 2574 | const char *i915_cache_level_str(int type); |
2489 | 2575 | ||
2576 | /* i915_cmd_parser.c */ | ||
2577 | void i915_cmd_parser_init_ring(struct intel_ring_buffer *ring); | ||
2578 | bool i915_needs_cmd_parser(struct intel_ring_buffer *ring); | ||
2579 | int i915_parse_cmds(struct intel_ring_buffer *ring, | ||
2580 | struct drm_i915_gem_object *batch_obj, | ||
2581 | u32 batch_start_offset, | ||
2582 | bool is_master); | ||
2583 | |||
2490 | /* i915_suspend.c */ | 2584 | /* i915_suspend.c */ |
2491 | extern int i915_save_state(struct drm_device *dev); | 2585 | extern int i915_save_state(struct drm_device *dev); |
2492 | extern int i915_restore_state(struct drm_device *dev); | 2586 | extern int i915_restore_state(struct drm_device *dev); |
@@ -2565,6 +2659,7 @@ extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); | |||
2565 | extern void intel_modeset_setup_hw_state(struct drm_device *dev, | 2659 | extern void intel_modeset_setup_hw_state(struct drm_device *dev, |
2566 | bool force_restore); | 2660 | bool force_restore); |
2567 | extern void i915_redisable_vga(struct drm_device *dev); | 2661 | extern void i915_redisable_vga(struct drm_device *dev); |
2662 | extern void i915_redisable_vga_power_on(struct drm_device *dev); | ||
2568 | extern bool intel_fbc_enabled(struct drm_device *dev); | 2663 | extern bool intel_fbc_enabled(struct drm_device *dev); |
2569 | extern void intel_disable_fbc(struct drm_device *dev); | 2664 | extern void intel_disable_fbc(struct drm_device *dev); |
2570 | extern bool ironlake_set_drps(struct drm_device *dev, u8 val); | 2665 | extern bool ironlake_set_drps(struct drm_device *dev, u8 val); |
@@ -2599,6 +2694,7 @@ extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e, | |||
2599 | */ | 2694 | */ |
2600 | void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine); | 2695 | void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine); |
2601 | void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine); | 2696 | void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine); |
2697 | void assert_force_wake_inactive(struct drm_i915_private *dev_priv); | ||
2602 | 2698 | ||
2603 | int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val); | 2699 | int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val); |
2604 | int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val); | 2700 | int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 3618bb0cda0a..177c20722656 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -61,6 +61,7 @@ static unsigned long i915_gem_inactive_scan(struct shrinker *shrinker, | |||
61 | static unsigned long i915_gem_purge(struct drm_i915_private *dev_priv, long target); | 61 | static unsigned long i915_gem_purge(struct drm_i915_private *dev_priv, long target); |
62 | static unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv); | 62 | static unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv); |
63 | static void i915_gem_object_truncate(struct drm_i915_gem_object *obj); | 63 | static void i915_gem_object_truncate(struct drm_i915_gem_object *obj); |
64 | static void i915_gem_retire_requests_ring(struct intel_ring_buffer *ring); | ||
64 | 65 | ||
65 | static bool cpu_cache_is_coherent(struct drm_device *dev, | 66 | static bool cpu_cache_is_coherent(struct drm_device *dev, |
66 | enum i915_cache_level level) | 67 | enum i915_cache_level level) |
@@ -326,6 +327,42 @@ __copy_from_user_swizzled(char *gpu_vaddr, int gpu_offset, | |||
326 | return 0; | 327 | return 0; |
327 | } | 328 | } |
328 | 329 | ||
330 | /* | ||
331 | * Pins the specified object's pages and synchronizes the object with | ||
332 | * GPU accesses. Sets needs_clflush to non-zero if the caller should | ||
333 | * flush the object from the CPU cache. | ||
334 | */ | ||
335 | int i915_gem_obj_prepare_shmem_read(struct drm_i915_gem_object *obj, | ||
336 | int *needs_clflush) | ||
337 | { | ||
338 | int ret; | ||
339 | |||
340 | *needs_clflush = 0; | ||
341 | |||
342 | if (!obj->base.filp) | ||
343 | return -EINVAL; | ||
344 | |||
345 | if (!(obj->base.read_domains & I915_GEM_DOMAIN_CPU)) { | ||
346 | /* If we're not in the cpu read domain, set ourself into the gtt | ||
347 | * read domain and manually flush cachelines (if required). This | ||
348 | * optimizes for the case when the gpu will dirty the data | ||
349 | * anyway again before the next pread happens. */ | ||
350 | *needs_clflush = !cpu_cache_is_coherent(obj->base.dev, | ||
351 | obj->cache_level); | ||
352 | ret = i915_gem_object_wait_rendering(obj, true); | ||
353 | if (ret) | ||
354 | return ret; | ||
355 | } | ||
356 | |||
357 | ret = i915_gem_object_get_pages(obj); | ||
358 | if (ret) | ||
359 | return ret; | ||
360 | |||
361 | i915_gem_object_pin_pages(obj); | ||
362 | |||
363 | return ret; | ||
364 | } | ||
365 | |||
329 | /* Per-page copy function for the shmem pread fastpath. | 366 | /* Per-page copy function for the shmem pread fastpath. |
330 | * Flushes invalid cachelines before reading the target if | 367 | * Flushes invalid cachelines before reading the target if |
331 | * needs_clflush is set. */ | 368 | * needs_clflush is set. */ |
@@ -423,23 +460,10 @@ i915_gem_shmem_pread(struct drm_device *dev, | |||
423 | 460 | ||
424 | obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); | 461 | obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); |
425 | 462 | ||
426 | if (!(obj->base.read_domains & I915_GEM_DOMAIN_CPU)) { | 463 | ret = i915_gem_obj_prepare_shmem_read(obj, &needs_clflush); |
427 | /* If we're not in the cpu read domain, set ourself into the gtt | ||
428 | * read domain and manually flush cachelines (if required). This | ||
429 | * optimizes for the case when the gpu will dirty the data | ||
430 | * anyway again before the next pread happens. */ | ||
431 | needs_clflush = !cpu_cache_is_coherent(dev, obj->cache_level); | ||
432 | ret = i915_gem_object_wait_rendering(obj, true); | ||
433 | if (ret) | ||
434 | return ret; | ||
435 | } | ||
436 | |||
437 | ret = i915_gem_object_get_pages(obj); | ||
438 | if (ret) | 464 | if (ret) |
439 | return ret; | 465 | return ret; |
440 | 466 | ||
441 | i915_gem_object_pin_pages(obj); | ||
442 | |||
443 | offset = args->offset; | 467 | offset = args->offset; |
444 | 468 | ||
445 | for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, | 469 | for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, |
@@ -2148,7 +2172,6 @@ int __i915_add_request(struct intel_ring_buffer *ring, | |||
2148 | drm_i915_private_t *dev_priv = ring->dev->dev_private; | 2172 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
2149 | struct drm_i915_gem_request *request; | 2173 | struct drm_i915_gem_request *request; |
2150 | u32 request_ring_position, request_start; | 2174 | u32 request_ring_position, request_start; |
2151 | int was_empty; | ||
2152 | int ret; | 2175 | int ret; |
2153 | 2176 | ||
2154 | request_start = intel_ring_get_tail(ring); | 2177 | request_start = intel_ring_get_tail(ring); |
@@ -2199,7 +2222,6 @@ int __i915_add_request(struct intel_ring_buffer *ring, | |||
2199 | i915_gem_context_reference(request->ctx); | 2222 | i915_gem_context_reference(request->ctx); |
2200 | 2223 | ||
2201 | request->emitted_jiffies = jiffies; | 2224 | request->emitted_jiffies = jiffies; |
2202 | was_empty = list_empty(&ring->request_list); | ||
2203 | list_add_tail(&request->list, &ring->request_list); | 2225 | list_add_tail(&request->list, &ring->request_list); |
2204 | request->file_priv = NULL; | 2226 | request->file_priv = NULL; |
2205 | 2227 | ||
@@ -2220,13 +2242,11 @@ int __i915_add_request(struct intel_ring_buffer *ring, | |||
2220 | if (!dev_priv->ums.mm_suspended) { | 2242 | if (!dev_priv->ums.mm_suspended) { |
2221 | i915_queue_hangcheck(ring->dev); | 2243 | i915_queue_hangcheck(ring->dev); |
2222 | 2244 | ||
2223 | if (was_empty) { | 2245 | cancel_delayed_work_sync(&dev_priv->mm.idle_work); |
2224 | cancel_delayed_work_sync(&dev_priv->mm.idle_work); | 2246 | queue_delayed_work(dev_priv->wq, |
2225 | queue_delayed_work(dev_priv->wq, | 2247 | &dev_priv->mm.retire_work, |
2226 | &dev_priv->mm.retire_work, | 2248 | round_jiffies_up_relative(HZ)); |
2227 | round_jiffies_up_relative(HZ)); | 2249 | intel_mark_busy(dev_priv->dev); |
2228 | intel_mark_busy(dev_priv->dev); | ||
2229 | } | ||
2230 | } | 2250 | } |
2231 | 2251 | ||
2232 | if (out_seqno) | 2252 | if (out_seqno) |
@@ -2259,14 +2279,13 @@ static bool i915_context_is_banned(struct drm_i915_private *dev_priv, | |||
2259 | return true; | 2279 | return true; |
2260 | 2280 | ||
2261 | if (elapsed <= DRM_I915_CTX_BAN_PERIOD) { | 2281 | if (elapsed <= DRM_I915_CTX_BAN_PERIOD) { |
2262 | if (dev_priv->gpu_error.stop_rings == 0 && | 2282 | if (!i915_gem_context_is_default(ctx)) { |
2263 | i915_gem_context_is_default(ctx)) { | ||
2264 | DRM_ERROR("gpu hanging too fast, banning!\n"); | ||
2265 | } else { | ||
2266 | DRM_DEBUG("context hanging too fast, banning!\n"); | 2283 | DRM_DEBUG("context hanging too fast, banning!\n"); |
2284 | return true; | ||
2285 | } else if (dev_priv->gpu_error.stop_rings == 0) { | ||
2286 | DRM_ERROR("gpu hanging too fast, banning!\n"); | ||
2287 | return true; | ||
2267 | } | 2288 | } |
2268 | |||
2269 | return true; | ||
2270 | } | 2289 | } |
2271 | 2290 | ||
2272 | return false; | 2291 | return false; |
@@ -2303,11 +2322,13 @@ static void i915_gem_free_request(struct drm_i915_gem_request *request) | |||
2303 | kfree(request); | 2322 | kfree(request); |
2304 | } | 2323 | } |
2305 | 2324 | ||
2306 | static struct drm_i915_gem_request * | 2325 | struct drm_i915_gem_request * |
2307 | i915_gem_find_first_non_complete(struct intel_ring_buffer *ring) | 2326 | i915_gem_find_active_request(struct intel_ring_buffer *ring) |
2308 | { | 2327 | { |
2309 | struct drm_i915_gem_request *request; | 2328 | struct drm_i915_gem_request *request; |
2310 | const u32 completed_seqno = ring->get_seqno(ring, false); | 2329 | u32 completed_seqno; |
2330 | |||
2331 | completed_seqno = ring->get_seqno(ring, false); | ||
2311 | 2332 | ||
2312 | list_for_each_entry(request, &ring->request_list, list) { | 2333 | list_for_each_entry(request, &ring->request_list, list) { |
2313 | if (i915_seqno_passed(completed_seqno, request->seqno)) | 2334 | if (i915_seqno_passed(completed_seqno, request->seqno)) |
@@ -2325,7 +2346,7 @@ static void i915_gem_reset_ring_status(struct drm_i915_private *dev_priv, | |||
2325 | struct drm_i915_gem_request *request; | 2346 | struct drm_i915_gem_request *request; |
2326 | bool ring_hung; | 2347 | bool ring_hung; |
2327 | 2348 | ||
2328 | request = i915_gem_find_first_non_complete(ring); | 2349 | request = i915_gem_find_active_request(ring); |
2329 | 2350 | ||
2330 | if (request == NULL) | 2351 | if (request == NULL) |
2331 | return; | 2352 | return; |
@@ -2417,7 +2438,7 @@ void i915_gem_reset(struct drm_device *dev) | |||
2417 | /** | 2438 | /** |
2418 | * This function clears the request list as sequence numbers are passed. | 2439 | * This function clears the request list as sequence numbers are passed. |
2419 | */ | 2440 | */ |
2420 | void | 2441 | static void |
2421 | i915_gem_retire_requests_ring(struct intel_ring_buffer *ring) | 2442 | i915_gem_retire_requests_ring(struct intel_ring_buffer *ring) |
2422 | { | 2443 | { |
2423 | uint32_t seqno; | 2444 | uint32_t seqno; |
@@ -2744,7 +2765,7 @@ int i915_vma_unbind(struct i915_vma *vma) | |||
2744 | 2765 | ||
2745 | i915_gem_gtt_finish_object(obj); | 2766 | i915_gem_gtt_finish_object(obj); |
2746 | 2767 | ||
2747 | list_del(&vma->mm_list); | 2768 | list_del_init(&vma->mm_list); |
2748 | /* Avoid an unnecessary call to unbind on rebind. */ | 2769 | /* Avoid an unnecessary call to unbind on rebind. */ |
2749 | if (i915_is_ggtt(vma->vm)) | 2770 | if (i915_is_ggtt(vma->vm)) |
2750 | obj->map_and_fenceable = true; | 2771 | obj->map_and_fenceable = true; |
@@ -4860,6 +4881,7 @@ int i915_gem_open(struct drm_device *dev, struct drm_file *file) | |||
4860 | 4881 | ||
4861 | file->driver_priv = file_priv; | 4882 | file->driver_priv = file_priv; |
4862 | file_priv->dev_priv = dev->dev_private; | 4883 | file_priv->dev_priv = dev->dev_private; |
4884 | file_priv->file = file; | ||
4863 | 4885 | ||
4864 | spin_lock_init(&file_priv->mm.lock); | 4886 | spin_lock_init(&file_priv->mm.lock); |
4865 | INIT_LIST_HEAD(&file_priv->mm.request_list); | 4887 | INIT_LIST_HEAD(&file_priv->mm.request_list); |
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index f8c21a6dd663..ce41cff84346 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c | |||
@@ -99,6 +99,50 @@ | |||
99 | static int do_switch(struct intel_ring_buffer *ring, | 99 | static int do_switch(struct intel_ring_buffer *ring, |
100 | struct i915_hw_context *to); | 100 | struct i915_hw_context *to); |
101 | 101 | ||
102 | static void do_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt) | ||
103 | { | ||
104 | struct drm_device *dev = ppgtt->base.dev; | ||
105 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
106 | struct i915_address_space *vm = &ppgtt->base; | ||
107 | |||
108 | if (ppgtt == dev_priv->mm.aliasing_ppgtt || | ||
109 | (list_empty(&vm->active_list) && list_empty(&vm->inactive_list))) { | ||
110 | ppgtt->base.cleanup(&ppgtt->base); | ||
111 | return; | ||
112 | } | ||
113 | |||
114 | /* | ||
115 | * Make sure vmas are unbound before we take down the drm_mm | ||
116 | * | ||
117 | * FIXME: Proper refcounting should take care of this, this shouldn't be | ||
118 | * needed at all. | ||
119 | */ | ||
120 | if (!list_empty(&vm->active_list)) { | ||
121 | struct i915_vma *vma; | ||
122 | |||
123 | list_for_each_entry(vma, &vm->active_list, mm_list) | ||
124 | if (WARN_ON(list_empty(&vma->vma_link) || | ||
125 | list_is_singular(&vma->vma_link))) | ||
126 | break; | ||
127 | |||
128 | i915_gem_evict_vm(&ppgtt->base, true); | ||
129 | } else { | ||
130 | i915_gem_retire_requests(dev); | ||
131 | i915_gem_evict_vm(&ppgtt->base, false); | ||
132 | } | ||
133 | |||
134 | ppgtt->base.cleanup(&ppgtt->base); | ||
135 | } | ||
136 | |||
137 | static void ppgtt_release(struct kref *kref) | ||
138 | { | ||
139 | struct i915_hw_ppgtt *ppgtt = | ||
140 | container_of(kref, struct i915_hw_ppgtt, ref); | ||
141 | |||
142 | do_ppgtt_cleanup(ppgtt); | ||
143 | kfree(ppgtt); | ||
144 | } | ||
145 | |||
102 | static size_t get_context_alignment(struct drm_device *dev) | 146 | static size_t get_context_alignment(struct drm_device *dev) |
103 | { | 147 | { |
104 | if (IS_GEN6(dev)) | 148 | if (IS_GEN6(dev)) |
@@ -714,7 +758,7 @@ unpin_out: | |||
714 | * i915_switch_context() - perform a GPU context switch. | 758 | * i915_switch_context() - perform a GPU context switch. |
715 | * @ring: ring for which we'll execute the context switch | 759 | * @ring: ring for which we'll execute the context switch |
716 | * @file_priv: file_priv associated with the context, may be NULL | 760 | * @file_priv: file_priv associated with the context, may be NULL |
717 | * @id: context id number | 761 | * @to: the context to switch to |
718 | * | 762 | * |
719 | * The context life cycle is simple. The context refcount is incremented and | 763 | * The context life cycle is simple. The context refcount is incremented and |
720 | * decremented by 1 and create and destroy. If the context is in use by the GPU, | 764 | * decremented by 1 and create and destroy. If the context is in use by the GPU, |
@@ -746,9 +790,6 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, | |||
746 | struct i915_hw_context *ctx; | 790 | struct i915_hw_context *ctx; |
747 | int ret; | 791 | int ret; |
748 | 792 | ||
749 | if (!(dev->driver->driver_features & DRIVER_GEM)) | ||
750 | return -ENODEV; | ||
751 | |||
752 | if (!HAS_HW_CONTEXTS(dev)) | 793 | if (!HAS_HW_CONTEXTS(dev)) |
753 | return -ENODEV; | 794 | return -ENODEV; |
754 | 795 | ||
@@ -775,9 +816,6 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, | |||
775 | struct i915_hw_context *ctx; | 816 | struct i915_hw_context *ctx; |
776 | int ret; | 817 | int ret; |
777 | 818 | ||
778 | if (!(dev->driver->driver_features & DRIVER_GEM)) | ||
779 | return -ENODEV; | ||
780 | |||
781 | if (args->ctx_id == DEFAULT_CONTEXT_ID) | 819 | if (args->ctx_id == DEFAULT_CONTEXT_ID) |
782 | return -ENOENT; | 820 | return -ENOENT; |
783 | 821 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index d7229ad2bd22..3851a1b1dc88 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -1182,6 +1182,24 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1182 | } | 1182 | } |
1183 | batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND; | 1183 | batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND; |
1184 | 1184 | ||
1185 | if (i915_needs_cmd_parser(ring)) { | ||
1186 | ret = i915_parse_cmds(ring, | ||
1187 | batch_obj, | ||
1188 | args->batch_start_offset, | ||
1189 | file->is_master); | ||
1190 | if (ret) | ||
1191 | goto err; | ||
1192 | |||
1193 | /* | ||
1194 | * XXX: Actually do this when enabling batch copy... | ||
1195 | * | ||
1196 | * Set the DISPATCH_SECURE bit to remove the NON_SECURE bit | ||
1197 | * from MI_BATCH_BUFFER_START commands issued in the | ||
1198 | * dispatch_execbuffer implementations. We specifically don't | ||
1199 | * want that set when the command parser is enabled. | ||
1200 | */ | ||
1201 | } | ||
1202 | |||
1185 | /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure | 1203 | /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure |
1186 | * batch" bit. Hence we need to pin secure batches into the global gtt. | 1204 | * batch" bit. Hence we need to pin secure batches into the global gtt. |
1187 | * hsw should have this fixed, but bdw mucks it up again. */ | 1205 | * hsw should have this fixed, but bdw mucks it up again. */ |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 9673cffb07f3..63a6dc7a6bb6 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright © 2010 Daniel Vetter | 2 | * Copyright © 2010 Daniel Vetter |
3 | * Copyright © 2011-2014 Intel Corporation | ||
3 | * | 4 | * |
4 | * Permission is hereby granted, free of charge, to any person obtaining a | 5 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * copy of this software and associated documentation files (the "Software"), | 6 | * copy of this software and associated documentation files (the "Software"), |
@@ -29,6 +30,29 @@ | |||
29 | #include "i915_trace.h" | 30 | #include "i915_trace.h" |
30 | #include "intel_drv.h" | 31 | #include "intel_drv.h" |
31 | 32 | ||
33 | bool intel_enable_ppgtt(struct drm_device *dev, bool full) | ||
34 | { | ||
35 | if (i915.enable_ppgtt == 0 || !HAS_ALIASING_PPGTT(dev)) | ||
36 | return false; | ||
37 | |||
38 | if (i915.enable_ppgtt == 1 && full) | ||
39 | return false; | ||
40 | |||
41 | #ifdef CONFIG_INTEL_IOMMU | ||
42 | /* Disable ppgtt on SNB if VT-d is on. */ | ||
43 | if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) { | ||
44 | DRM_INFO("Disabling PPGTT because VT-d is on\n"); | ||
45 | return false; | ||
46 | } | ||
47 | #endif | ||
48 | |||
49 | /* Full ppgtt disabled by default for now due to issues. */ | ||
50 | if (full) | ||
51 | return false; /* HAS_PPGTT(dev) */ | ||
52 | else | ||
53 | return HAS_ALIASING_PPGTT(dev); | ||
54 | } | ||
55 | |||
32 | #define GEN6_PPGTT_PD_ENTRIES 512 | 56 | #define GEN6_PPGTT_PD_ENTRIES 512 |
33 | #define I915_PPGTT_PT_ENTRIES (PAGE_SIZE / sizeof(gen6_gtt_pte_t)) | 57 | #define I915_PPGTT_PT_ENTRIES (PAGE_SIZE / sizeof(gen6_gtt_pte_t)) |
34 | typedef uint64_t gen8_gtt_pte_t; | 58 | typedef uint64_t gen8_gtt_pte_t; |
@@ -64,7 +88,19 @@ typedef gen8_gtt_pte_t gen8_ppgtt_pde_t; | |||
64 | 88 | ||
65 | #define GEN8_PTES_PER_PAGE (PAGE_SIZE / sizeof(gen8_gtt_pte_t)) | 89 | #define GEN8_PTES_PER_PAGE (PAGE_SIZE / sizeof(gen8_gtt_pte_t)) |
66 | #define GEN8_PDES_PER_PAGE (PAGE_SIZE / sizeof(gen8_ppgtt_pde_t)) | 90 | #define GEN8_PDES_PER_PAGE (PAGE_SIZE / sizeof(gen8_ppgtt_pde_t)) |
67 | #define GEN8_LEGACY_PDPS 4 | 91 | |
92 | /* GEN8 legacy style addressis defined as a 3 level page table: | ||
93 | * 31:30 | 29:21 | 20:12 | 11:0 | ||
94 | * PDPE | PDE | PTE | offset | ||
95 | * The difference as compared to normal x86 3 level page table is the PDPEs are | ||
96 | * programmed via register. | ||
97 | */ | ||
98 | #define GEN8_PDPE_SHIFT 30 | ||
99 | #define GEN8_PDPE_MASK 0x3 | ||
100 | #define GEN8_PDE_SHIFT 21 | ||
101 | #define GEN8_PDE_MASK 0x1ff | ||
102 | #define GEN8_PTE_SHIFT 12 | ||
103 | #define GEN8_PTE_MASK 0x1ff | ||
68 | 104 | ||
69 | #define PPAT_UNCACHED_INDEX (_PAGE_PWT | _PAGE_PCD) | 105 | #define PPAT_UNCACHED_INDEX (_PAGE_PWT | _PAGE_PCD) |
70 | #define PPAT_CACHED_PDE_INDEX 0 /* WB LLC */ | 106 | #define PPAT_CACHED_PDE_INDEX 0 /* WB LLC */ |
@@ -254,84 +290,113 @@ static int gen8_mm_switch(struct i915_hw_ppgtt *ppgtt, | |||
254 | } | 290 | } |
255 | 291 | ||
256 | static void gen8_ppgtt_clear_range(struct i915_address_space *vm, | 292 | static void gen8_ppgtt_clear_range(struct i915_address_space *vm, |
257 | unsigned first_entry, | 293 | uint64_t start, |
258 | unsigned num_entries, | 294 | uint64_t length, |
259 | bool use_scratch) | 295 | bool use_scratch) |
260 | { | 296 | { |
261 | struct i915_hw_ppgtt *ppgtt = | 297 | struct i915_hw_ppgtt *ppgtt = |
262 | container_of(vm, struct i915_hw_ppgtt, base); | 298 | container_of(vm, struct i915_hw_ppgtt, base); |
263 | gen8_gtt_pte_t *pt_vaddr, scratch_pte; | 299 | gen8_gtt_pte_t *pt_vaddr, scratch_pte; |
264 | unsigned act_pt = first_entry / GEN8_PTES_PER_PAGE; | 300 | unsigned pdpe = start >> GEN8_PDPE_SHIFT & GEN8_PDPE_MASK; |
265 | unsigned first_pte = first_entry % GEN8_PTES_PER_PAGE; | 301 | unsigned pde = start >> GEN8_PDE_SHIFT & GEN8_PDE_MASK; |
302 | unsigned pte = start >> GEN8_PTE_SHIFT & GEN8_PTE_MASK; | ||
303 | unsigned num_entries = length >> PAGE_SHIFT; | ||
266 | unsigned last_pte, i; | 304 | unsigned last_pte, i; |
267 | 305 | ||
268 | scratch_pte = gen8_pte_encode(ppgtt->base.scratch.addr, | 306 | scratch_pte = gen8_pte_encode(ppgtt->base.scratch.addr, |
269 | I915_CACHE_LLC, use_scratch); | 307 | I915_CACHE_LLC, use_scratch); |
270 | 308 | ||
271 | while (num_entries) { | 309 | while (num_entries) { |
272 | struct page *page_table = &ppgtt->gen8_pt_pages[act_pt]; | 310 | struct page *page_table = ppgtt->gen8_pt_pages[pdpe][pde]; |
273 | 311 | ||
274 | last_pte = first_pte + num_entries; | 312 | last_pte = pte + num_entries; |
275 | if (last_pte > GEN8_PTES_PER_PAGE) | 313 | if (last_pte > GEN8_PTES_PER_PAGE) |
276 | last_pte = GEN8_PTES_PER_PAGE; | 314 | last_pte = GEN8_PTES_PER_PAGE; |
277 | 315 | ||
278 | pt_vaddr = kmap_atomic(page_table); | 316 | pt_vaddr = kmap_atomic(page_table); |
279 | 317 | ||
280 | for (i = first_pte; i < last_pte; i++) | 318 | for (i = pte; i < last_pte; i++) { |
281 | pt_vaddr[i] = scratch_pte; | 319 | pt_vaddr[i] = scratch_pte; |
320 | num_entries--; | ||
321 | } | ||
282 | 322 | ||
283 | kunmap_atomic(pt_vaddr); | 323 | kunmap_atomic(pt_vaddr); |
284 | 324 | ||
285 | num_entries -= last_pte - first_pte; | 325 | pte = 0; |
286 | first_pte = 0; | 326 | if (++pde == GEN8_PDES_PER_PAGE) { |
287 | act_pt++; | 327 | pdpe++; |
328 | pde = 0; | ||
329 | } | ||
288 | } | 330 | } |
289 | } | 331 | } |
290 | 332 | ||
291 | static void gen8_ppgtt_insert_entries(struct i915_address_space *vm, | 333 | static void gen8_ppgtt_insert_entries(struct i915_address_space *vm, |
292 | struct sg_table *pages, | 334 | struct sg_table *pages, |
293 | unsigned first_entry, | 335 | uint64_t start, |
294 | enum i915_cache_level cache_level) | 336 | enum i915_cache_level cache_level) |
295 | { | 337 | { |
296 | struct i915_hw_ppgtt *ppgtt = | 338 | struct i915_hw_ppgtt *ppgtt = |
297 | container_of(vm, struct i915_hw_ppgtt, base); | 339 | container_of(vm, struct i915_hw_ppgtt, base); |
298 | gen8_gtt_pte_t *pt_vaddr; | 340 | gen8_gtt_pte_t *pt_vaddr; |
299 | unsigned act_pt = first_entry / GEN8_PTES_PER_PAGE; | 341 | unsigned pdpe = start >> GEN8_PDPE_SHIFT & GEN8_PDPE_MASK; |
300 | unsigned act_pte = first_entry % GEN8_PTES_PER_PAGE; | 342 | unsigned pde = start >> GEN8_PDE_SHIFT & GEN8_PDE_MASK; |
343 | unsigned pte = start >> GEN8_PTE_SHIFT & GEN8_PTE_MASK; | ||
301 | struct sg_page_iter sg_iter; | 344 | struct sg_page_iter sg_iter; |
302 | 345 | ||
303 | pt_vaddr = NULL; | 346 | pt_vaddr = NULL; |
347 | |||
304 | for_each_sg_page(pages->sgl, &sg_iter, pages->nents, 0) { | 348 | for_each_sg_page(pages->sgl, &sg_iter, pages->nents, 0) { |
349 | if (WARN_ON(pdpe >= GEN8_LEGACY_PDPS)) | ||
350 | break; | ||
351 | |||
305 | if (pt_vaddr == NULL) | 352 | if (pt_vaddr == NULL) |
306 | pt_vaddr = kmap_atomic(&ppgtt->gen8_pt_pages[act_pt]); | 353 | pt_vaddr = kmap_atomic(ppgtt->gen8_pt_pages[pdpe][pde]); |
307 | 354 | ||
308 | pt_vaddr[act_pte] = | 355 | pt_vaddr[pte] = |
309 | gen8_pte_encode(sg_page_iter_dma_address(&sg_iter), | 356 | gen8_pte_encode(sg_page_iter_dma_address(&sg_iter), |
310 | cache_level, true); | 357 | cache_level, true); |
311 | if (++act_pte == GEN8_PTES_PER_PAGE) { | 358 | if (++pte == GEN8_PTES_PER_PAGE) { |
312 | kunmap_atomic(pt_vaddr); | 359 | kunmap_atomic(pt_vaddr); |
313 | pt_vaddr = NULL; | 360 | pt_vaddr = NULL; |
314 | act_pt++; | 361 | if (++pde == GEN8_PDES_PER_PAGE) { |
315 | act_pte = 0; | 362 | pdpe++; |
363 | pde = 0; | ||
364 | } | ||
365 | pte = 0; | ||
316 | } | 366 | } |
317 | } | 367 | } |
318 | if (pt_vaddr) | 368 | if (pt_vaddr) |
319 | kunmap_atomic(pt_vaddr); | 369 | kunmap_atomic(pt_vaddr); |
320 | } | 370 | } |
321 | 371 | ||
322 | static void gen8_ppgtt_free(struct i915_hw_ppgtt *ppgtt) | 372 | static void gen8_free_page_tables(struct page **pt_pages) |
323 | { | 373 | { |
324 | int i; | 374 | int i; |
325 | 375 | ||
326 | for (i = 0; i < ppgtt->num_pd_pages ; i++) | 376 | if (pt_pages == NULL) |
377 | return; | ||
378 | |||
379 | for (i = 0; i < GEN8_PDES_PER_PAGE; i++) | ||
380 | if (pt_pages[i]) | ||
381 | __free_pages(pt_pages[i], 0); | ||
382 | } | ||
383 | |||
384 | static void gen8_ppgtt_free(const struct i915_hw_ppgtt *ppgtt) | ||
385 | { | ||
386 | int i; | ||
387 | |||
388 | for (i = 0; i < ppgtt->num_pd_pages; i++) { | ||
389 | gen8_free_page_tables(ppgtt->gen8_pt_pages[i]); | ||
390 | kfree(ppgtt->gen8_pt_pages[i]); | ||
327 | kfree(ppgtt->gen8_pt_dma_addr[i]); | 391 | kfree(ppgtt->gen8_pt_dma_addr[i]); |
392 | } | ||
328 | 393 | ||
329 | __free_pages(ppgtt->gen8_pt_pages, get_order(ppgtt->num_pt_pages << PAGE_SHIFT)); | ||
330 | __free_pages(ppgtt->pd_pages, get_order(ppgtt->num_pd_pages << PAGE_SHIFT)); | 394 | __free_pages(ppgtt->pd_pages, get_order(ppgtt->num_pd_pages << PAGE_SHIFT)); |
331 | } | 395 | } |
332 | 396 | ||
333 | static void gen8_ppgtt_unmap_pages(struct i915_hw_ppgtt *ppgtt) | 397 | static void gen8_ppgtt_unmap_pages(struct i915_hw_ppgtt *ppgtt) |
334 | { | 398 | { |
399 | struct pci_dev *hwdev = ppgtt->base.dev->pdev; | ||
335 | int i, j; | 400 | int i, j; |
336 | 401 | ||
337 | for (i = 0; i < ppgtt->num_pd_pages; i++) { | 402 | for (i = 0; i < ppgtt->num_pd_pages; i++) { |
@@ -340,18 +405,14 @@ static void gen8_ppgtt_unmap_pages(struct i915_hw_ppgtt *ppgtt) | |||
340 | if (!ppgtt->pd_dma_addr[i]) | 405 | if (!ppgtt->pd_dma_addr[i]) |
341 | continue; | 406 | continue; |
342 | 407 | ||
343 | pci_unmap_page(ppgtt->base.dev->pdev, | 408 | pci_unmap_page(hwdev, ppgtt->pd_dma_addr[i], PAGE_SIZE, |
344 | ppgtt->pd_dma_addr[i], | 409 | PCI_DMA_BIDIRECTIONAL); |
345 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | ||
346 | 410 | ||
347 | for (j = 0; j < GEN8_PDES_PER_PAGE; j++) { | 411 | for (j = 0; j < GEN8_PDES_PER_PAGE; j++) { |
348 | dma_addr_t addr = ppgtt->gen8_pt_dma_addr[i][j]; | 412 | dma_addr_t addr = ppgtt->gen8_pt_dma_addr[i][j]; |
349 | if (addr) | 413 | if (addr) |
350 | pci_unmap_page(ppgtt->base.dev->pdev, | 414 | pci_unmap_page(hwdev, addr, PAGE_SIZE, |
351 | addr, | 415 | PCI_DMA_BIDIRECTIONAL); |
352 | PAGE_SIZE, | ||
353 | PCI_DMA_BIDIRECTIONAL); | ||
354 | |||
355 | } | 416 | } |
356 | } | 417 | } |
357 | } | 418 | } |
@@ -368,88 +429,198 @@ static void gen8_ppgtt_cleanup(struct i915_address_space *vm) | |||
368 | gen8_ppgtt_free(ppgtt); | 429 | gen8_ppgtt_free(ppgtt); |
369 | } | 430 | } |
370 | 431 | ||
371 | /** | 432 | static struct page **__gen8_alloc_page_tables(void) |
372 | * GEN8 legacy ppgtt programming is accomplished through 4 PDP registers with a | ||
373 | * net effect resembling a 2-level page table in normal x86 terms. Each PDP | ||
374 | * represents 1GB of memory | ||
375 | * 4 * 512 * 512 * 4096 = 4GB legacy 32b address space. | ||
376 | * | ||
377 | * TODO: Do something with the size parameter | ||
378 | **/ | ||
379 | static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size) | ||
380 | { | 433 | { |
381 | struct page *pt_pages; | 434 | struct page **pt_pages; |
382 | int i, j, ret = -ENOMEM; | 435 | int i; |
383 | const int max_pdp = DIV_ROUND_UP(size, 1 << 30); | ||
384 | const int num_pt_pages = GEN8_PDES_PER_PAGE * max_pdp; | ||
385 | 436 | ||
386 | if (size % (1<<30)) | 437 | pt_pages = kcalloc(GEN8_PDES_PER_PAGE, sizeof(struct page *), GFP_KERNEL); |
387 | DRM_INFO("Pages will be wasted unless GTT size (%llu) is divisible by 1GB\n", size); | 438 | if (!pt_pages) |
439 | return ERR_PTR(-ENOMEM); | ||
440 | |||
441 | for (i = 0; i < GEN8_PDES_PER_PAGE; i++) { | ||
442 | pt_pages[i] = alloc_page(GFP_KERNEL); | ||
443 | if (!pt_pages[i]) | ||
444 | goto bail; | ||
445 | } | ||
388 | 446 | ||
389 | /* FIXME: split allocation into smaller pieces. For now we only ever do | 447 | return pt_pages; |
390 | * this once, but with full PPGTT, the multiple contiguous allocations | 448 | |
391 | * will be bad. | 449 | bail: |
450 | gen8_free_page_tables(pt_pages); | ||
451 | kfree(pt_pages); | ||
452 | return ERR_PTR(-ENOMEM); | ||
453 | } | ||
454 | |||
455 | static int gen8_ppgtt_allocate_page_tables(struct i915_hw_ppgtt *ppgtt, | ||
456 | const int max_pdp) | ||
457 | { | ||
458 | struct page **pt_pages[GEN8_LEGACY_PDPS]; | ||
459 | int i, ret; | ||
460 | |||
461 | for (i = 0; i < max_pdp; i++) { | ||
462 | pt_pages[i] = __gen8_alloc_page_tables(); | ||
463 | if (IS_ERR(pt_pages[i])) { | ||
464 | ret = PTR_ERR(pt_pages[i]); | ||
465 | goto unwind_out; | ||
466 | } | ||
467 | } | ||
468 | |||
469 | /* NB: Avoid touching gen8_pt_pages until last to keep the allocation, | ||
470 | * "atomic" - for cleanup purposes. | ||
392 | */ | 471 | */ |
472 | for (i = 0; i < max_pdp; i++) | ||
473 | ppgtt->gen8_pt_pages[i] = pt_pages[i]; | ||
474 | |||
475 | return 0; | ||
476 | |||
477 | unwind_out: | ||
478 | while (i--) { | ||
479 | gen8_free_page_tables(pt_pages[i]); | ||
480 | kfree(pt_pages[i]); | ||
481 | } | ||
482 | |||
483 | return ret; | ||
484 | } | ||
485 | |||
486 | static int gen8_ppgtt_allocate_dma(struct i915_hw_ppgtt *ppgtt) | ||
487 | { | ||
488 | int i; | ||
489 | |||
490 | for (i = 0; i < ppgtt->num_pd_pages; i++) { | ||
491 | ppgtt->gen8_pt_dma_addr[i] = kcalloc(GEN8_PDES_PER_PAGE, | ||
492 | sizeof(dma_addr_t), | ||
493 | GFP_KERNEL); | ||
494 | if (!ppgtt->gen8_pt_dma_addr[i]) | ||
495 | return -ENOMEM; | ||
496 | } | ||
497 | |||
498 | return 0; | ||
499 | } | ||
500 | |||
501 | static int gen8_ppgtt_allocate_page_directories(struct i915_hw_ppgtt *ppgtt, | ||
502 | const int max_pdp) | ||
503 | { | ||
393 | ppgtt->pd_pages = alloc_pages(GFP_KERNEL, get_order(max_pdp << PAGE_SHIFT)); | 504 | ppgtt->pd_pages = alloc_pages(GFP_KERNEL, get_order(max_pdp << PAGE_SHIFT)); |
394 | if (!ppgtt->pd_pages) | 505 | if (!ppgtt->pd_pages) |
395 | return -ENOMEM; | 506 | return -ENOMEM; |
396 | 507 | ||
397 | pt_pages = alloc_pages(GFP_KERNEL, get_order(num_pt_pages << PAGE_SHIFT)); | 508 | ppgtt->num_pd_pages = 1 << get_order(max_pdp << PAGE_SHIFT); |
398 | if (!pt_pages) { | 509 | BUG_ON(ppgtt->num_pd_pages > GEN8_LEGACY_PDPS); |
510 | |||
511 | return 0; | ||
512 | } | ||
513 | |||
514 | static int gen8_ppgtt_alloc(struct i915_hw_ppgtt *ppgtt, | ||
515 | const int max_pdp) | ||
516 | { | ||
517 | int ret; | ||
518 | |||
519 | ret = gen8_ppgtt_allocate_page_directories(ppgtt, max_pdp); | ||
520 | if (ret) | ||
521 | return ret; | ||
522 | |||
523 | ret = gen8_ppgtt_allocate_page_tables(ppgtt, max_pdp); | ||
524 | if (ret) { | ||
399 | __free_pages(ppgtt->pd_pages, get_order(max_pdp << PAGE_SHIFT)); | 525 | __free_pages(ppgtt->pd_pages, get_order(max_pdp << PAGE_SHIFT)); |
400 | return -ENOMEM; | 526 | return ret; |
401 | } | 527 | } |
402 | 528 | ||
403 | ppgtt->gen8_pt_pages = pt_pages; | ||
404 | ppgtt->num_pd_pages = 1 << get_order(max_pdp << PAGE_SHIFT); | ||
405 | ppgtt->num_pt_pages = 1 << get_order(num_pt_pages << PAGE_SHIFT); | ||
406 | ppgtt->num_pd_entries = max_pdp * GEN8_PDES_PER_PAGE; | 529 | ppgtt->num_pd_entries = max_pdp * GEN8_PDES_PER_PAGE; |
407 | ppgtt->enable = gen8_ppgtt_enable; | ||
408 | ppgtt->switch_mm = gen8_mm_switch; | ||
409 | ppgtt->base.clear_range = gen8_ppgtt_clear_range; | ||
410 | ppgtt->base.insert_entries = gen8_ppgtt_insert_entries; | ||
411 | ppgtt->base.cleanup = gen8_ppgtt_cleanup; | ||
412 | ppgtt->base.start = 0; | ||
413 | ppgtt->base.total = ppgtt->num_pt_pages * GEN8_PTES_PER_PAGE * PAGE_SIZE; | ||
414 | 530 | ||
415 | BUG_ON(ppgtt->num_pd_pages > GEN8_LEGACY_PDPS); | 531 | ret = gen8_ppgtt_allocate_dma(ppgtt); |
532 | if (ret) | ||
533 | gen8_ppgtt_free(ppgtt); | ||
416 | 534 | ||
417 | /* | 535 | return ret; |
418 | * - Create a mapping for the page directories. | 536 | } |
419 | * - For each page directory: | ||
420 | * allocate space for page table mappings. | ||
421 | * map each page table | ||
422 | */ | ||
423 | for (i = 0; i < max_pdp; i++) { | ||
424 | dma_addr_t temp; | ||
425 | temp = pci_map_page(ppgtt->base.dev->pdev, | ||
426 | &ppgtt->pd_pages[i], 0, | ||
427 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | ||
428 | if (pci_dma_mapping_error(ppgtt->base.dev->pdev, temp)) | ||
429 | goto err_out; | ||
430 | 537 | ||
431 | ppgtt->pd_dma_addr[i] = temp; | 538 | static int gen8_ppgtt_setup_page_directories(struct i915_hw_ppgtt *ppgtt, |
539 | const int pd) | ||
540 | { | ||
541 | dma_addr_t pd_addr; | ||
542 | int ret; | ||
432 | 543 | ||
433 | ppgtt->gen8_pt_dma_addr[i] = kmalloc(sizeof(dma_addr_t) * GEN8_PDES_PER_PAGE, GFP_KERNEL); | 544 | pd_addr = pci_map_page(ppgtt->base.dev->pdev, |
434 | if (!ppgtt->gen8_pt_dma_addr[i]) | 545 | &ppgtt->pd_pages[pd], 0, |
435 | goto err_out; | 546 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
436 | 547 | ||
437 | for (j = 0; j < GEN8_PDES_PER_PAGE; j++) { | 548 | ret = pci_dma_mapping_error(ppgtt->base.dev->pdev, pd_addr); |
438 | struct page *p = &pt_pages[i * GEN8_PDES_PER_PAGE + j]; | 549 | if (ret) |
439 | temp = pci_map_page(ppgtt->base.dev->pdev, | 550 | return ret; |
440 | p, 0, PAGE_SIZE, | 551 | |
441 | PCI_DMA_BIDIRECTIONAL); | 552 | ppgtt->pd_dma_addr[pd] = pd_addr; |
553 | |||
554 | return 0; | ||
555 | } | ||
442 | 556 | ||
443 | if (pci_dma_mapping_error(ppgtt->base.dev->pdev, temp)) | 557 | static int gen8_ppgtt_setup_page_tables(struct i915_hw_ppgtt *ppgtt, |
444 | goto err_out; | 558 | const int pd, |
559 | const int pt) | ||
560 | { | ||
561 | dma_addr_t pt_addr; | ||
562 | struct page *p; | ||
563 | int ret; | ||
445 | 564 | ||
446 | ppgtt->gen8_pt_dma_addr[i][j] = temp; | 565 | p = ppgtt->gen8_pt_pages[pd][pt]; |
566 | pt_addr = pci_map_page(ppgtt->base.dev->pdev, | ||
567 | p, 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | ||
568 | ret = pci_dma_mapping_error(ppgtt->base.dev->pdev, pt_addr); | ||
569 | if (ret) | ||
570 | return ret; | ||
571 | |||
572 | ppgtt->gen8_pt_dma_addr[pd][pt] = pt_addr; | ||
573 | |||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | /** | ||
578 | * GEN8 legacy ppgtt programming is accomplished through a max 4 PDP registers | ||
579 | * with a net effect resembling a 2-level page table in normal x86 terms. Each | ||
580 | * PDP represents 1GB of memory 4 * 512 * 512 * 4096 = 4GB legacy 32b address | ||
581 | * space. | ||
582 | * | ||
583 | * FIXME: split allocation into smaller pieces. For now we only ever do this | ||
584 | * once, but with full PPGTT, the multiple contiguous allocations will be bad. | ||
585 | * TODO: Do something with the size parameter | ||
586 | */ | ||
587 | static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size) | ||
588 | { | ||
589 | const int max_pdp = DIV_ROUND_UP(size, 1 << 30); | ||
590 | const int min_pt_pages = GEN8_PDES_PER_PAGE * max_pdp; | ||
591 | int i, j, ret; | ||
592 | |||
593 | if (size % (1<<30)) | ||
594 | DRM_INFO("Pages will be wasted unless GTT size (%llu) is divisible by 1GB\n", size); | ||
595 | |||
596 | /* 1. Do all our allocations for page directories and page tables. */ | ||
597 | ret = gen8_ppgtt_alloc(ppgtt, max_pdp); | ||
598 | if (ret) | ||
599 | return ret; | ||
600 | |||
601 | /* | ||
602 | * 2. Create DMA mappings for the page directories and page tables. | ||
603 | */ | ||
604 | for (i = 0; i < max_pdp; i++) { | ||
605 | ret = gen8_ppgtt_setup_page_directories(ppgtt, i); | ||
606 | if (ret) | ||
607 | goto bail; | ||
608 | |||
609 | for (j = 0; j < GEN8_PDES_PER_PAGE; j++) { | ||
610 | ret = gen8_ppgtt_setup_page_tables(ppgtt, i, j); | ||
611 | if (ret) | ||
612 | goto bail; | ||
447 | } | 613 | } |
448 | } | 614 | } |
449 | 615 | ||
450 | /* For now, the PPGTT helper functions all require that the PDEs are | 616 | /* |
617 | * 3. Map all the page directory entires to point to the page tables | ||
618 | * we've allocated. | ||
619 | * | ||
620 | * For now, the PPGTT helper functions all require that the PDEs are | ||
451 | * plugged in correctly. So we do that now/here. For aliasing PPGTT, we | 621 | * plugged in correctly. So we do that now/here. For aliasing PPGTT, we |
452 | * will never need to touch the PDEs again */ | 622 | * will never need to touch the PDEs again. |
623 | */ | ||
453 | for (i = 0; i < max_pdp; i++) { | 624 | for (i = 0; i < max_pdp; i++) { |
454 | gen8_ppgtt_pde_t *pd_vaddr; | 625 | gen8_ppgtt_pde_t *pd_vaddr; |
455 | pd_vaddr = kmap_atomic(&ppgtt->pd_pages[i]); | 626 | pd_vaddr = kmap_atomic(&ppgtt->pd_pages[i]); |
@@ -461,20 +632,26 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size) | |||
461 | kunmap_atomic(pd_vaddr); | 632 | kunmap_atomic(pd_vaddr); |
462 | } | 633 | } |
463 | 634 | ||
464 | ppgtt->base.clear_range(&ppgtt->base, 0, | 635 | ppgtt->enable = gen8_ppgtt_enable; |
465 | ppgtt->num_pd_entries * GEN8_PTES_PER_PAGE, | 636 | ppgtt->switch_mm = gen8_mm_switch; |
466 | true); | 637 | ppgtt->base.clear_range = gen8_ppgtt_clear_range; |
638 | ppgtt->base.insert_entries = gen8_ppgtt_insert_entries; | ||
639 | ppgtt->base.cleanup = gen8_ppgtt_cleanup; | ||
640 | ppgtt->base.start = 0; | ||
641 | ppgtt->base.total = ppgtt->num_pd_entries * GEN8_PTES_PER_PAGE * PAGE_SIZE; | ||
642 | |||
643 | ppgtt->base.clear_range(&ppgtt->base, 0, ppgtt->base.total, true); | ||
467 | 644 | ||
468 | DRM_DEBUG_DRIVER("Allocated %d pages for page directories (%d wasted)\n", | 645 | DRM_DEBUG_DRIVER("Allocated %d pages for page directories (%d wasted)\n", |
469 | ppgtt->num_pd_pages, ppgtt->num_pd_pages - max_pdp); | 646 | ppgtt->num_pd_pages, ppgtt->num_pd_pages - max_pdp); |
470 | DRM_DEBUG_DRIVER("Allocated %d pages for page tables (%lld wasted)\n", | 647 | DRM_DEBUG_DRIVER("Allocated %d pages for page tables (%lld wasted)\n", |
471 | ppgtt->num_pt_pages, | 648 | ppgtt->num_pd_entries, |
472 | (ppgtt->num_pt_pages - num_pt_pages) + | 649 | (ppgtt->num_pd_entries - min_pt_pages) + size % (1<<30)); |
473 | size % (1<<30)); | ||
474 | return 0; | 650 | return 0; |
475 | 651 | ||
476 | err_out: | 652 | bail: |
477 | ppgtt->base.cleanup(&ppgtt->base); | 653 | gen8_ppgtt_unmap_pages(ppgtt); |
654 | gen8_ppgtt_free(ppgtt); | ||
478 | return ret; | 655 | return ret; |
479 | } | 656 | } |
480 | 657 | ||
@@ -776,13 +953,15 @@ static int gen6_ppgtt_enable(struct i915_hw_ppgtt *ppgtt) | |||
776 | 953 | ||
777 | /* PPGTT support for Sandybdrige/Gen6 and later */ | 954 | /* PPGTT support for Sandybdrige/Gen6 and later */ |
778 | static void gen6_ppgtt_clear_range(struct i915_address_space *vm, | 955 | static void gen6_ppgtt_clear_range(struct i915_address_space *vm, |
779 | unsigned first_entry, | 956 | uint64_t start, |
780 | unsigned num_entries, | 957 | uint64_t length, |
781 | bool use_scratch) | 958 | bool use_scratch) |
782 | { | 959 | { |
783 | struct i915_hw_ppgtt *ppgtt = | 960 | struct i915_hw_ppgtt *ppgtt = |
784 | container_of(vm, struct i915_hw_ppgtt, base); | 961 | container_of(vm, struct i915_hw_ppgtt, base); |
785 | gen6_gtt_pte_t *pt_vaddr, scratch_pte; | 962 | gen6_gtt_pte_t *pt_vaddr, scratch_pte; |
963 | unsigned first_entry = start >> PAGE_SHIFT; | ||
964 | unsigned num_entries = length >> PAGE_SHIFT; | ||
786 | unsigned act_pt = first_entry / I915_PPGTT_PT_ENTRIES; | 965 | unsigned act_pt = first_entry / I915_PPGTT_PT_ENTRIES; |
787 | unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES; | 966 | unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES; |
788 | unsigned last_pte, i; | 967 | unsigned last_pte, i; |
@@ -809,12 +988,13 @@ static void gen6_ppgtt_clear_range(struct i915_address_space *vm, | |||
809 | 988 | ||
810 | static void gen6_ppgtt_insert_entries(struct i915_address_space *vm, | 989 | static void gen6_ppgtt_insert_entries(struct i915_address_space *vm, |
811 | struct sg_table *pages, | 990 | struct sg_table *pages, |
812 | unsigned first_entry, | 991 | uint64_t start, |
813 | enum i915_cache_level cache_level) | 992 | enum i915_cache_level cache_level) |
814 | { | 993 | { |
815 | struct i915_hw_ppgtt *ppgtt = | 994 | struct i915_hw_ppgtt *ppgtt = |
816 | container_of(vm, struct i915_hw_ppgtt, base); | 995 | container_of(vm, struct i915_hw_ppgtt, base); |
817 | gen6_gtt_pte_t *pt_vaddr; | 996 | gen6_gtt_pte_t *pt_vaddr; |
997 | unsigned first_entry = start >> PAGE_SHIFT; | ||
818 | unsigned act_pt = first_entry / I915_PPGTT_PT_ENTRIES; | 998 | unsigned act_pt = first_entry / I915_PPGTT_PT_ENTRIES; |
819 | unsigned act_pte = first_entry % I915_PPGTT_PT_ENTRIES; | 999 | unsigned act_pte = first_entry % I915_PPGTT_PT_ENTRIES; |
820 | struct sg_page_iter sg_iter; | 1000 | struct sg_page_iter sg_iter; |
@@ -838,38 +1018,49 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm, | |||
838 | kunmap_atomic(pt_vaddr); | 1018 | kunmap_atomic(pt_vaddr); |
839 | } | 1019 | } |
840 | 1020 | ||
841 | static void gen6_ppgtt_cleanup(struct i915_address_space *vm) | 1021 | static void gen6_ppgtt_unmap_pages(struct i915_hw_ppgtt *ppgtt) |
842 | { | 1022 | { |
843 | struct i915_hw_ppgtt *ppgtt = | ||
844 | container_of(vm, struct i915_hw_ppgtt, base); | ||
845 | int i; | 1023 | int i; |
846 | 1024 | ||
847 | list_del(&vm->global_link); | ||
848 | drm_mm_takedown(&ppgtt->base.mm); | ||
849 | drm_mm_remove_node(&ppgtt->node); | ||
850 | |||
851 | if (ppgtt->pt_dma_addr) { | 1025 | if (ppgtt->pt_dma_addr) { |
852 | for (i = 0; i < ppgtt->num_pd_entries; i++) | 1026 | for (i = 0; i < ppgtt->num_pd_entries; i++) |
853 | pci_unmap_page(ppgtt->base.dev->pdev, | 1027 | pci_unmap_page(ppgtt->base.dev->pdev, |
854 | ppgtt->pt_dma_addr[i], | 1028 | ppgtt->pt_dma_addr[i], |
855 | 4096, PCI_DMA_BIDIRECTIONAL); | 1029 | 4096, PCI_DMA_BIDIRECTIONAL); |
856 | } | 1030 | } |
1031 | } | ||
1032 | |||
1033 | static void gen6_ppgtt_free(struct i915_hw_ppgtt *ppgtt) | ||
1034 | { | ||
1035 | int i; | ||
857 | 1036 | ||
858 | kfree(ppgtt->pt_dma_addr); | 1037 | kfree(ppgtt->pt_dma_addr); |
859 | for (i = 0; i < ppgtt->num_pd_entries; i++) | 1038 | for (i = 0; i < ppgtt->num_pd_entries; i++) |
860 | __free_page(ppgtt->pt_pages[i]); | 1039 | __free_page(ppgtt->pt_pages[i]); |
861 | kfree(ppgtt->pt_pages); | 1040 | kfree(ppgtt->pt_pages); |
862 | kfree(ppgtt); | ||
863 | } | 1041 | } |
864 | 1042 | ||
865 | static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) | 1043 | static void gen6_ppgtt_cleanup(struct i915_address_space *vm) |
1044 | { | ||
1045 | struct i915_hw_ppgtt *ppgtt = | ||
1046 | container_of(vm, struct i915_hw_ppgtt, base); | ||
1047 | |||
1048 | list_del(&vm->global_link); | ||
1049 | drm_mm_takedown(&ppgtt->base.mm); | ||
1050 | drm_mm_remove_node(&ppgtt->node); | ||
1051 | |||
1052 | gen6_ppgtt_unmap_pages(ppgtt); | ||
1053 | gen6_ppgtt_free(ppgtt); | ||
1054 | } | ||
1055 | |||
1056 | static int gen6_ppgtt_allocate_page_directories(struct i915_hw_ppgtt *ppgtt) | ||
866 | { | 1057 | { |
867 | #define GEN6_PD_ALIGN (PAGE_SIZE * 16) | 1058 | #define GEN6_PD_ALIGN (PAGE_SIZE * 16) |
868 | #define GEN6_PD_SIZE (GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE) | 1059 | #define GEN6_PD_SIZE (GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE) |
869 | struct drm_device *dev = ppgtt->base.dev; | 1060 | struct drm_device *dev = ppgtt->base.dev; |
870 | struct drm_i915_private *dev_priv = dev->dev_private; | 1061 | struct drm_i915_private *dev_priv = dev->dev_private; |
871 | bool retried = false; | 1062 | bool retried = false; |
872 | int i, ret; | 1063 | int ret; |
873 | 1064 | ||
874 | /* PPGTT PDEs reside in the GGTT and consists of 512 entries. The | 1065 | /* PPGTT PDEs reside in the GGTT and consists of 512 entries. The |
875 | * allocator works in address space sizes, so it's multiplied by page | 1066 | * allocator works in address space sizes, so it's multiplied by page |
@@ -896,42 +1087,60 @@ alloc: | |||
896 | if (ppgtt->node.start < dev_priv->gtt.mappable_end) | 1087 | if (ppgtt->node.start < dev_priv->gtt.mappable_end) |
897 | DRM_DEBUG("Forced to use aperture for PDEs\n"); | 1088 | DRM_DEBUG("Forced to use aperture for PDEs\n"); |
898 | 1089 | ||
899 | ppgtt->base.pte_encode = dev_priv->gtt.base.pte_encode; | ||
900 | ppgtt->num_pd_entries = GEN6_PPGTT_PD_ENTRIES; | 1090 | ppgtt->num_pd_entries = GEN6_PPGTT_PD_ENTRIES; |
901 | if (IS_GEN6(dev)) { | 1091 | return ret; |
902 | ppgtt->enable = gen6_ppgtt_enable; | 1092 | } |
903 | ppgtt->switch_mm = gen6_mm_switch; | 1093 | |
904 | } else if (IS_HASWELL(dev)) { | 1094 | static int gen6_ppgtt_allocate_page_tables(struct i915_hw_ppgtt *ppgtt) |
905 | ppgtt->enable = gen7_ppgtt_enable; | 1095 | { |
906 | ppgtt->switch_mm = hsw_mm_switch; | 1096 | int i; |
907 | } else if (IS_GEN7(dev)) { | 1097 | |
908 | ppgtt->enable = gen7_ppgtt_enable; | ||
909 | ppgtt->switch_mm = gen7_mm_switch; | ||
910 | } else | ||
911 | BUG(); | ||
912 | ppgtt->base.clear_range = gen6_ppgtt_clear_range; | ||
913 | ppgtt->base.insert_entries = gen6_ppgtt_insert_entries; | ||
914 | ppgtt->base.cleanup = gen6_ppgtt_cleanup; | ||
915 | ppgtt->base.scratch = dev_priv->gtt.base.scratch; | ||
916 | ppgtt->base.start = 0; | ||
917 | ppgtt->base.total = GEN6_PPGTT_PD_ENTRIES * I915_PPGTT_PT_ENTRIES * PAGE_SIZE; | ||
918 | ppgtt->pt_pages = kcalloc(ppgtt->num_pd_entries, sizeof(struct page *), | 1098 | ppgtt->pt_pages = kcalloc(ppgtt->num_pd_entries, sizeof(struct page *), |
919 | GFP_KERNEL); | 1099 | GFP_KERNEL); |
920 | if (!ppgtt->pt_pages) { | 1100 | |
921 | drm_mm_remove_node(&ppgtt->node); | 1101 | if (!ppgtt->pt_pages) |
922 | return -ENOMEM; | 1102 | return -ENOMEM; |
923 | } | ||
924 | 1103 | ||
925 | for (i = 0; i < ppgtt->num_pd_entries; i++) { | 1104 | for (i = 0; i < ppgtt->num_pd_entries; i++) { |
926 | ppgtt->pt_pages[i] = alloc_page(GFP_KERNEL); | 1105 | ppgtt->pt_pages[i] = alloc_page(GFP_KERNEL); |
927 | if (!ppgtt->pt_pages[i]) | 1106 | if (!ppgtt->pt_pages[i]) { |
928 | goto err_pt_alloc; | 1107 | gen6_ppgtt_free(ppgtt); |
1108 | return -ENOMEM; | ||
1109 | } | ||
1110 | } | ||
1111 | |||
1112 | return 0; | ||
1113 | } | ||
1114 | |||
1115 | static int gen6_ppgtt_alloc(struct i915_hw_ppgtt *ppgtt) | ||
1116 | { | ||
1117 | int ret; | ||
1118 | |||
1119 | ret = gen6_ppgtt_allocate_page_directories(ppgtt); | ||
1120 | if (ret) | ||
1121 | return ret; | ||
1122 | |||
1123 | ret = gen6_ppgtt_allocate_page_tables(ppgtt); | ||
1124 | if (ret) { | ||
1125 | drm_mm_remove_node(&ppgtt->node); | ||
1126 | return ret; | ||
929 | } | 1127 | } |
930 | 1128 | ||
931 | ppgtt->pt_dma_addr = kcalloc(ppgtt->num_pd_entries, sizeof(dma_addr_t), | 1129 | ppgtt->pt_dma_addr = kcalloc(ppgtt->num_pd_entries, sizeof(dma_addr_t), |
932 | GFP_KERNEL); | 1130 | GFP_KERNEL); |
933 | if (!ppgtt->pt_dma_addr) | 1131 | if (!ppgtt->pt_dma_addr) { |
934 | goto err_pt_alloc; | 1132 | drm_mm_remove_node(&ppgtt->node); |
1133 | gen6_ppgtt_free(ppgtt); | ||
1134 | return -ENOMEM; | ||
1135 | } | ||
1136 | |||
1137 | return 0; | ||
1138 | } | ||
1139 | |||
1140 | static int gen6_ppgtt_setup_page_tables(struct i915_hw_ppgtt *ppgtt) | ||
1141 | { | ||
1142 | struct drm_device *dev = ppgtt->base.dev; | ||
1143 | int i; | ||
935 | 1144 | ||
936 | for (i = 0; i < ppgtt->num_pd_entries; i++) { | 1145 | for (i = 0; i < ppgtt->num_pd_entries; i++) { |
937 | dma_addr_t pt_addr; | 1146 | dma_addr_t pt_addr; |
@@ -940,41 +1149,63 @@ alloc: | |||
940 | PCI_DMA_BIDIRECTIONAL); | 1149 | PCI_DMA_BIDIRECTIONAL); |
941 | 1150 | ||
942 | if (pci_dma_mapping_error(dev->pdev, pt_addr)) { | 1151 | if (pci_dma_mapping_error(dev->pdev, pt_addr)) { |
943 | ret = -EIO; | 1152 | gen6_ppgtt_unmap_pages(ppgtt); |
944 | goto err_pd_pin; | 1153 | return -EIO; |
945 | |||
946 | } | 1154 | } |
1155 | |||
947 | ppgtt->pt_dma_addr[i] = pt_addr; | 1156 | ppgtt->pt_dma_addr[i] = pt_addr; |
948 | } | 1157 | } |
949 | 1158 | ||
950 | ppgtt->base.clear_range(&ppgtt->base, 0, | 1159 | return 0; |
951 | ppgtt->num_pd_entries * I915_PPGTT_PT_ENTRIES, true); | 1160 | } |
1161 | |||
1162 | static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) | ||
1163 | { | ||
1164 | struct drm_device *dev = ppgtt->base.dev; | ||
1165 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1166 | int ret; | ||
1167 | |||
1168 | ppgtt->base.pte_encode = dev_priv->gtt.base.pte_encode; | ||
1169 | if (IS_GEN6(dev)) { | ||
1170 | ppgtt->enable = gen6_ppgtt_enable; | ||
1171 | ppgtt->switch_mm = gen6_mm_switch; | ||
1172 | } else if (IS_HASWELL(dev)) { | ||
1173 | ppgtt->enable = gen7_ppgtt_enable; | ||
1174 | ppgtt->switch_mm = hsw_mm_switch; | ||
1175 | } else if (IS_GEN7(dev)) { | ||
1176 | ppgtt->enable = gen7_ppgtt_enable; | ||
1177 | ppgtt->switch_mm = gen7_mm_switch; | ||
1178 | } else | ||
1179 | BUG(); | ||
1180 | |||
1181 | ret = gen6_ppgtt_alloc(ppgtt); | ||
1182 | if (ret) | ||
1183 | return ret; | ||
1184 | |||
1185 | ret = gen6_ppgtt_setup_page_tables(ppgtt); | ||
1186 | if (ret) { | ||
1187 | gen6_ppgtt_free(ppgtt); | ||
1188 | return ret; | ||
1189 | } | ||
1190 | |||
1191 | ppgtt->base.clear_range = gen6_ppgtt_clear_range; | ||
1192 | ppgtt->base.insert_entries = gen6_ppgtt_insert_entries; | ||
1193 | ppgtt->base.cleanup = gen6_ppgtt_cleanup; | ||
1194 | ppgtt->base.scratch = dev_priv->gtt.base.scratch; | ||
1195 | ppgtt->base.start = 0; | ||
1196 | ppgtt->base.total = GEN6_PPGTT_PD_ENTRIES * I915_PPGTT_PT_ENTRIES * PAGE_SIZE; | ||
952 | ppgtt->debug_dump = gen6_dump_ppgtt; | 1197 | ppgtt->debug_dump = gen6_dump_ppgtt; |
953 | 1198 | ||
954 | DRM_DEBUG_DRIVER("Allocated pde space (%ldM) at GTT entry: %lx\n", | ||
955 | ppgtt->node.size >> 20, | ||
956 | ppgtt->node.start / PAGE_SIZE); | ||
957 | ppgtt->pd_offset = | 1199 | ppgtt->pd_offset = |
958 | ppgtt->node.start / PAGE_SIZE * sizeof(gen6_gtt_pte_t); | 1200 | ppgtt->node.start / PAGE_SIZE * sizeof(gen6_gtt_pte_t); |
959 | 1201 | ||
960 | return 0; | 1202 | ppgtt->base.clear_range(&ppgtt->base, 0, ppgtt->base.total, true); |
961 | 1203 | ||
962 | err_pd_pin: | 1204 | DRM_DEBUG_DRIVER("Allocated pde space (%ldM) at GTT entry: %lx\n", |
963 | if (ppgtt->pt_dma_addr) { | 1205 | ppgtt->node.size >> 20, |
964 | for (i--; i >= 0; i--) | 1206 | ppgtt->node.start / PAGE_SIZE); |
965 | pci_unmap_page(dev->pdev, ppgtt->pt_dma_addr[i], | ||
966 | 4096, PCI_DMA_BIDIRECTIONAL); | ||
967 | } | ||
968 | err_pt_alloc: | ||
969 | kfree(ppgtt->pt_dma_addr); | ||
970 | for (i = 0; i < ppgtt->num_pd_entries; i++) { | ||
971 | if (ppgtt->pt_pages[i]) | ||
972 | __free_page(ppgtt->pt_pages[i]); | ||
973 | } | ||
974 | kfree(ppgtt->pt_pages); | ||
975 | drm_mm_remove_node(&ppgtt->node); | ||
976 | 1207 | ||
977 | return ret; | 1208 | return 0; |
978 | } | 1209 | } |
979 | 1210 | ||
980 | int i915_gem_init_ppgtt(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt) | 1211 | int i915_gem_init_ppgtt(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt) |
@@ -1012,20 +1243,17 @@ ppgtt_bind_vma(struct i915_vma *vma, | |||
1012 | enum i915_cache_level cache_level, | 1243 | enum i915_cache_level cache_level, |
1013 | u32 flags) | 1244 | u32 flags) |
1014 | { | 1245 | { |
1015 | const unsigned long entry = vma->node.start >> PAGE_SHIFT; | ||
1016 | |||
1017 | WARN_ON(flags); | 1246 | WARN_ON(flags); |
1018 | 1247 | ||
1019 | vma->vm->insert_entries(vma->vm, vma->obj->pages, entry, cache_level); | 1248 | vma->vm->insert_entries(vma->vm, vma->obj->pages, vma->node.start, |
1249 | cache_level); | ||
1020 | } | 1250 | } |
1021 | 1251 | ||
1022 | static void ppgtt_unbind_vma(struct i915_vma *vma) | 1252 | static void ppgtt_unbind_vma(struct i915_vma *vma) |
1023 | { | 1253 | { |
1024 | const unsigned long entry = vma->node.start >> PAGE_SHIFT; | ||
1025 | |||
1026 | vma->vm->clear_range(vma->vm, | 1254 | vma->vm->clear_range(vma->vm, |
1027 | entry, | 1255 | vma->node.start, |
1028 | vma->obj->base.size >> PAGE_SHIFT, | 1256 | vma->obj->base.size, |
1029 | true); | 1257 | true); |
1030 | } | 1258 | } |
1031 | 1259 | ||
@@ -1109,8 +1337,8 @@ void i915_gem_suspend_gtt_mappings(struct drm_device *dev) | |||
1109 | i915_check_and_clear_faults(dev); | 1337 | i915_check_and_clear_faults(dev); |
1110 | 1338 | ||
1111 | dev_priv->gtt.base.clear_range(&dev_priv->gtt.base, | 1339 | dev_priv->gtt.base.clear_range(&dev_priv->gtt.base, |
1112 | dev_priv->gtt.base.start / PAGE_SIZE, | 1340 | dev_priv->gtt.base.start, |
1113 | dev_priv->gtt.base.total / PAGE_SIZE, | 1341 | dev_priv->gtt.base.total, |
1114 | false); | 1342 | false); |
1115 | } | 1343 | } |
1116 | 1344 | ||
@@ -1124,8 +1352,8 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) | |||
1124 | 1352 | ||
1125 | /* First fill our portion of the GTT with scratch pages */ | 1353 | /* First fill our portion of the GTT with scratch pages */ |
1126 | dev_priv->gtt.base.clear_range(&dev_priv->gtt.base, | 1354 | dev_priv->gtt.base.clear_range(&dev_priv->gtt.base, |
1127 | dev_priv->gtt.base.start / PAGE_SIZE, | 1355 | dev_priv->gtt.base.start, |
1128 | dev_priv->gtt.base.total / PAGE_SIZE, | 1356 | dev_priv->gtt.base.total, |
1129 | true); | 1357 | true); |
1130 | 1358 | ||
1131 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { | 1359 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { |
@@ -1186,10 +1414,11 @@ static inline void gen8_set_pte(void __iomem *addr, gen8_gtt_pte_t pte) | |||
1186 | 1414 | ||
1187 | static void gen8_ggtt_insert_entries(struct i915_address_space *vm, | 1415 | static void gen8_ggtt_insert_entries(struct i915_address_space *vm, |
1188 | struct sg_table *st, | 1416 | struct sg_table *st, |
1189 | unsigned int first_entry, | 1417 | uint64_t start, |
1190 | enum i915_cache_level level) | 1418 | enum i915_cache_level level) |
1191 | { | 1419 | { |
1192 | struct drm_i915_private *dev_priv = vm->dev->dev_private; | 1420 | struct drm_i915_private *dev_priv = vm->dev->dev_private; |
1421 | unsigned first_entry = start >> PAGE_SHIFT; | ||
1193 | gen8_gtt_pte_t __iomem *gtt_entries = | 1422 | gen8_gtt_pte_t __iomem *gtt_entries = |
1194 | (gen8_gtt_pte_t __iomem *)dev_priv->gtt.gsm + first_entry; | 1423 | (gen8_gtt_pte_t __iomem *)dev_priv->gtt.gsm + first_entry; |
1195 | int i = 0; | 1424 | int i = 0; |
@@ -1231,10 +1460,11 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm, | |||
1231 | */ | 1460 | */ |
1232 | static void gen6_ggtt_insert_entries(struct i915_address_space *vm, | 1461 | static void gen6_ggtt_insert_entries(struct i915_address_space *vm, |
1233 | struct sg_table *st, | 1462 | struct sg_table *st, |
1234 | unsigned int first_entry, | 1463 | uint64_t start, |
1235 | enum i915_cache_level level) | 1464 | enum i915_cache_level level) |
1236 | { | 1465 | { |
1237 | struct drm_i915_private *dev_priv = vm->dev->dev_private; | 1466 | struct drm_i915_private *dev_priv = vm->dev->dev_private; |
1467 | unsigned first_entry = start >> PAGE_SHIFT; | ||
1238 | gen6_gtt_pte_t __iomem *gtt_entries = | 1468 | gen6_gtt_pte_t __iomem *gtt_entries = |
1239 | (gen6_gtt_pte_t __iomem *)dev_priv->gtt.gsm + first_entry; | 1469 | (gen6_gtt_pte_t __iomem *)dev_priv->gtt.gsm + first_entry; |
1240 | int i = 0; | 1470 | int i = 0; |
@@ -1266,11 +1496,13 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm, | |||
1266 | } | 1496 | } |
1267 | 1497 | ||
1268 | static void gen8_ggtt_clear_range(struct i915_address_space *vm, | 1498 | static void gen8_ggtt_clear_range(struct i915_address_space *vm, |
1269 | unsigned int first_entry, | 1499 | uint64_t start, |
1270 | unsigned int num_entries, | 1500 | uint64_t length, |
1271 | bool use_scratch) | 1501 | bool use_scratch) |
1272 | { | 1502 | { |
1273 | struct drm_i915_private *dev_priv = vm->dev->dev_private; | 1503 | struct drm_i915_private *dev_priv = vm->dev->dev_private; |
1504 | unsigned first_entry = start >> PAGE_SHIFT; | ||
1505 | unsigned num_entries = length >> PAGE_SHIFT; | ||
1274 | gen8_gtt_pte_t scratch_pte, __iomem *gtt_base = | 1506 | gen8_gtt_pte_t scratch_pte, __iomem *gtt_base = |
1275 | (gen8_gtt_pte_t __iomem *) dev_priv->gtt.gsm + first_entry; | 1507 | (gen8_gtt_pte_t __iomem *) dev_priv->gtt.gsm + first_entry; |
1276 | const int max_entries = gtt_total_entries(dev_priv->gtt) - first_entry; | 1508 | const int max_entries = gtt_total_entries(dev_priv->gtt) - first_entry; |
@@ -1290,11 +1522,13 @@ static void gen8_ggtt_clear_range(struct i915_address_space *vm, | |||
1290 | } | 1522 | } |
1291 | 1523 | ||
1292 | static void gen6_ggtt_clear_range(struct i915_address_space *vm, | 1524 | static void gen6_ggtt_clear_range(struct i915_address_space *vm, |
1293 | unsigned int first_entry, | 1525 | uint64_t start, |
1294 | unsigned int num_entries, | 1526 | uint64_t length, |
1295 | bool use_scratch) | 1527 | bool use_scratch) |
1296 | { | 1528 | { |
1297 | struct drm_i915_private *dev_priv = vm->dev->dev_private; | 1529 | struct drm_i915_private *dev_priv = vm->dev->dev_private; |
1530 | unsigned first_entry = start >> PAGE_SHIFT; | ||
1531 | unsigned num_entries = length >> PAGE_SHIFT; | ||
1298 | gen6_gtt_pte_t scratch_pte, __iomem *gtt_base = | 1532 | gen6_gtt_pte_t scratch_pte, __iomem *gtt_base = |
1299 | (gen6_gtt_pte_t __iomem *) dev_priv->gtt.gsm + first_entry; | 1533 | (gen6_gtt_pte_t __iomem *) dev_priv->gtt.gsm + first_entry; |
1300 | const int max_entries = gtt_total_entries(dev_priv->gtt) - first_entry; | 1534 | const int max_entries = gtt_total_entries(dev_priv->gtt) - first_entry; |
@@ -1327,10 +1561,12 @@ static void i915_ggtt_bind_vma(struct i915_vma *vma, | |||
1327 | } | 1561 | } |
1328 | 1562 | ||
1329 | static void i915_ggtt_clear_range(struct i915_address_space *vm, | 1563 | static void i915_ggtt_clear_range(struct i915_address_space *vm, |
1330 | unsigned int first_entry, | 1564 | uint64_t start, |
1331 | unsigned int num_entries, | 1565 | uint64_t length, |
1332 | bool unused) | 1566 | bool unused) |
1333 | { | 1567 | { |
1568 | unsigned first_entry = start >> PAGE_SHIFT; | ||
1569 | unsigned num_entries = length >> PAGE_SHIFT; | ||
1334 | intel_gtt_clear_range(first_entry, num_entries); | 1570 | intel_gtt_clear_range(first_entry, num_entries); |
1335 | } | 1571 | } |
1336 | 1572 | ||
@@ -1351,7 +1587,6 @@ static void ggtt_bind_vma(struct i915_vma *vma, | |||
1351 | struct drm_device *dev = vma->vm->dev; | 1587 | struct drm_device *dev = vma->vm->dev; |
1352 | struct drm_i915_private *dev_priv = dev->dev_private; | 1588 | struct drm_i915_private *dev_priv = dev->dev_private; |
1353 | struct drm_i915_gem_object *obj = vma->obj; | 1589 | struct drm_i915_gem_object *obj = vma->obj; |
1354 | const unsigned long entry = vma->node.start >> PAGE_SHIFT; | ||
1355 | 1590 | ||
1356 | /* If there is no aliasing PPGTT, or the caller needs a global mapping, | 1591 | /* If there is no aliasing PPGTT, or the caller needs a global mapping, |
1357 | * or we have a global mapping already but the cacheability flags have | 1592 | * or we have a global mapping already but the cacheability flags have |
@@ -1367,7 +1602,8 @@ static void ggtt_bind_vma(struct i915_vma *vma, | |||
1367 | if (!dev_priv->mm.aliasing_ppgtt || flags & GLOBAL_BIND) { | 1602 | if (!dev_priv->mm.aliasing_ppgtt || flags & GLOBAL_BIND) { |
1368 | if (!obj->has_global_gtt_mapping || | 1603 | if (!obj->has_global_gtt_mapping || |
1369 | (cache_level != obj->cache_level)) { | 1604 | (cache_level != obj->cache_level)) { |
1370 | vma->vm->insert_entries(vma->vm, obj->pages, entry, | 1605 | vma->vm->insert_entries(vma->vm, obj->pages, |
1606 | vma->node.start, | ||
1371 | cache_level); | 1607 | cache_level); |
1372 | obj->has_global_gtt_mapping = 1; | 1608 | obj->has_global_gtt_mapping = 1; |
1373 | } | 1609 | } |
@@ -1378,7 +1614,9 @@ static void ggtt_bind_vma(struct i915_vma *vma, | |||
1378 | (cache_level != obj->cache_level))) { | 1614 | (cache_level != obj->cache_level))) { |
1379 | struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt; | 1615 | struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt; |
1380 | appgtt->base.insert_entries(&appgtt->base, | 1616 | appgtt->base.insert_entries(&appgtt->base, |
1381 | vma->obj->pages, entry, cache_level); | 1617 | vma->obj->pages, |
1618 | vma->node.start, | ||
1619 | cache_level); | ||
1382 | vma->obj->has_aliasing_ppgtt_mapping = 1; | 1620 | vma->obj->has_aliasing_ppgtt_mapping = 1; |
1383 | } | 1621 | } |
1384 | } | 1622 | } |
@@ -1388,11 +1626,11 @@ static void ggtt_unbind_vma(struct i915_vma *vma) | |||
1388 | struct drm_device *dev = vma->vm->dev; | 1626 | struct drm_device *dev = vma->vm->dev; |
1389 | struct drm_i915_private *dev_priv = dev->dev_private; | 1627 | struct drm_i915_private *dev_priv = dev->dev_private; |
1390 | struct drm_i915_gem_object *obj = vma->obj; | 1628 | struct drm_i915_gem_object *obj = vma->obj; |
1391 | const unsigned long entry = vma->node.start >> PAGE_SHIFT; | ||
1392 | 1629 | ||
1393 | if (obj->has_global_gtt_mapping) { | 1630 | if (obj->has_global_gtt_mapping) { |
1394 | vma->vm->clear_range(vma->vm, entry, | 1631 | vma->vm->clear_range(vma->vm, |
1395 | vma->obj->base.size >> PAGE_SHIFT, | 1632 | vma->node.start, |
1633 | obj->base.size, | ||
1396 | true); | 1634 | true); |
1397 | obj->has_global_gtt_mapping = 0; | 1635 | obj->has_global_gtt_mapping = 0; |
1398 | } | 1636 | } |
@@ -1400,8 +1638,8 @@ static void ggtt_unbind_vma(struct i915_vma *vma) | |||
1400 | if (obj->has_aliasing_ppgtt_mapping) { | 1638 | if (obj->has_aliasing_ppgtt_mapping) { |
1401 | struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt; | 1639 | struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt; |
1402 | appgtt->base.clear_range(&appgtt->base, | 1640 | appgtt->base.clear_range(&appgtt->base, |
1403 | entry, | 1641 | vma->node.start, |
1404 | obj->base.size >> PAGE_SHIFT, | 1642 | obj->base.size, |
1405 | true); | 1643 | true); |
1406 | obj->has_aliasing_ppgtt_mapping = 0; | 1644 | obj->has_aliasing_ppgtt_mapping = 0; |
1407 | } | 1645 | } |
@@ -1486,14 +1724,14 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, | |||
1486 | 1724 | ||
1487 | /* Clear any non-preallocated blocks */ | 1725 | /* Clear any non-preallocated blocks */ |
1488 | drm_mm_for_each_hole(entry, &ggtt_vm->mm, hole_start, hole_end) { | 1726 | drm_mm_for_each_hole(entry, &ggtt_vm->mm, hole_start, hole_end) { |
1489 | const unsigned long count = (hole_end - hole_start) / PAGE_SIZE; | ||
1490 | DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n", | 1727 | DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n", |
1491 | hole_start, hole_end); | 1728 | hole_start, hole_end); |
1492 | ggtt_vm->clear_range(ggtt_vm, hole_start / PAGE_SIZE, count, true); | 1729 | ggtt_vm->clear_range(ggtt_vm, hole_start, |
1730 | hole_end - hole_start, true); | ||
1493 | } | 1731 | } |
1494 | 1732 | ||
1495 | /* And finally clear the reserved guard page */ | 1733 | /* And finally clear the reserved guard page */ |
1496 | ggtt_vm->clear_range(ggtt_vm, end / PAGE_SIZE - 1, 1, true); | 1734 | ggtt_vm->clear_range(ggtt_vm, end - PAGE_SIZE, PAGE_SIZE, true); |
1497 | } | 1735 | } |
1498 | 1736 | ||
1499 | void i915_gem_init_global_gtt(struct drm_device *dev) | 1737 | void i915_gem_init_global_gtt(struct drm_device *dev) |
@@ -1558,11 +1796,6 @@ static inline unsigned int gen8_get_total_gtt_size(u16 bdw_gmch_ctl) | |||
1558 | bdw_gmch_ctl &= BDW_GMCH_GGMS_MASK; | 1796 | bdw_gmch_ctl &= BDW_GMCH_GGMS_MASK; |
1559 | if (bdw_gmch_ctl) | 1797 | if (bdw_gmch_ctl) |
1560 | bdw_gmch_ctl = 1 << bdw_gmch_ctl; | 1798 | bdw_gmch_ctl = 1 << bdw_gmch_ctl; |
1561 | if (bdw_gmch_ctl > 4) { | ||
1562 | WARN_ON(!i915.preliminary_hw_support); | ||
1563 | return 4<<20; | ||
1564 | } | ||
1565 | |||
1566 | return bdw_gmch_ctl << 20; | 1799 | return bdw_gmch_ctl << 20; |
1567 | } | 1800 | } |
1568 | 1801 | ||
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 000b3694f349..144a5e2bc7ef 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c | |||
@@ -304,22 +304,54 @@ void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...) | |||
304 | va_end(args); | 304 | va_end(args); |
305 | } | 305 | } |
306 | 306 | ||
307 | static void print_error_obj(struct drm_i915_error_state_buf *m, | ||
308 | struct drm_i915_error_object *obj) | ||
309 | { | ||
310 | int page, offset, elt; | ||
311 | |||
312 | for (page = offset = 0; page < obj->page_count; page++) { | ||
313 | for (elt = 0; elt < PAGE_SIZE/4; elt++) { | ||
314 | err_printf(m, "%08x : %08x\n", offset, | ||
315 | obj->pages[page][elt]); | ||
316 | offset += 4; | ||
317 | } | ||
318 | } | ||
319 | } | ||
320 | |||
307 | int i915_error_state_to_str(struct drm_i915_error_state_buf *m, | 321 | int i915_error_state_to_str(struct drm_i915_error_state_buf *m, |
308 | const struct i915_error_state_file_priv *error_priv) | 322 | const struct i915_error_state_file_priv *error_priv) |
309 | { | 323 | { |
310 | struct drm_device *dev = error_priv->dev; | 324 | struct drm_device *dev = error_priv->dev; |
311 | drm_i915_private_t *dev_priv = dev->dev_private; | 325 | drm_i915_private_t *dev_priv = dev->dev_private; |
312 | struct drm_i915_error_state *error = error_priv->error; | 326 | struct drm_i915_error_state *error = error_priv->error; |
313 | int i, j, page, offset, elt; | 327 | int i, j, offset, elt; |
328 | int max_hangcheck_score; | ||
314 | 329 | ||
315 | if (!error) { | 330 | if (!error) { |
316 | err_printf(m, "no error state collected\n"); | 331 | err_printf(m, "no error state collected\n"); |
317 | goto out; | 332 | goto out; |
318 | } | 333 | } |
319 | 334 | ||
335 | err_printf(m, "%s\n", error->error_msg); | ||
320 | err_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, | 336 | err_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, |
321 | error->time.tv_usec); | 337 | error->time.tv_usec); |
322 | err_printf(m, "Kernel: " UTS_RELEASE "\n"); | 338 | err_printf(m, "Kernel: " UTS_RELEASE "\n"); |
339 | max_hangcheck_score = 0; | ||
340 | for (i = 0; i < ARRAY_SIZE(error->ring); i++) { | ||
341 | if (error->ring[i].hangcheck_score > max_hangcheck_score) | ||
342 | max_hangcheck_score = error->ring[i].hangcheck_score; | ||
343 | } | ||
344 | for (i = 0; i < ARRAY_SIZE(error->ring); i++) { | ||
345 | if (error->ring[i].hangcheck_score == max_hangcheck_score && | ||
346 | error->ring[i].pid != -1) { | ||
347 | err_printf(m, "Active process (on ring %s): %s [%d]\n", | ||
348 | ring_str(i), | ||
349 | error->ring[i].comm, | ||
350 | error->ring[i].pid); | ||
351 | } | ||
352 | } | ||
353 | err_printf(m, "Reset count: %u\n", error->reset_count); | ||
354 | err_printf(m, "Suspend count: %u\n", error->suspend_count); | ||
323 | err_printf(m, "PCI ID: 0x%04x\n", dev->pdev->device); | 355 | err_printf(m, "PCI ID: 0x%04x\n", dev->pdev->device); |
324 | err_printf(m, "EIR: 0x%08x\n", error->eir); | 356 | err_printf(m, "EIR: 0x%08x\n", error->eir); |
325 | err_printf(m, "IER: 0x%08x\n", error->ier); | 357 | err_printf(m, "IER: 0x%08x\n", error->ier); |
@@ -362,18 +394,23 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, | |||
362 | for (i = 0; i < ARRAY_SIZE(error->ring); i++) { | 394 | for (i = 0; i < ARRAY_SIZE(error->ring); i++) { |
363 | struct drm_i915_error_object *obj; | 395 | struct drm_i915_error_object *obj; |
364 | 396 | ||
365 | if ((obj = error->ring[i].batchbuffer)) { | 397 | obj = error->ring[i].batchbuffer; |
366 | err_printf(m, "%s --- gtt_offset = 0x%08x\n", | 398 | if (obj) { |
367 | dev_priv->ring[i].name, | 399 | err_puts(m, dev_priv->ring[i].name); |
400 | if (error->ring[i].pid != -1) | ||
401 | err_printf(m, " (submitted by %s [%d])", | ||
402 | error->ring[i].comm, | ||
403 | error->ring[i].pid); | ||
404 | err_printf(m, " --- gtt_offset = 0x%08x\n", | ||
368 | obj->gtt_offset); | 405 | obj->gtt_offset); |
369 | offset = 0; | 406 | print_error_obj(m, obj); |
370 | for (page = 0; page < obj->page_count; page++) { | 407 | } |
371 | for (elt = 0; elt < PAGE_SIZE/4; elt++) { | 408 | |
372 | err_printf(m, "%08x : %08x\n", offset, | 409 | obj = error->ring[i].wa_batchbuffer; |
373 | obj->pages[page][elt]); | 410 | if (obj) { |
374 | offset += 4; | 411 | err_printf(m, "%s (w/a) --- gtt_offset = 0x%08x\n", |
375 | } | 412 | dev_priv->ring[i].name, obj->gtt_offset); |
376 | } | 413 | print_error_obj(m, obj); |
377 | } | 414 | } |
378 | 415 | ||
379 | if (error->ring[i].num_requests) { | 416 | if (error->ring[i].num_requests) { |
@@ -392,15 +429,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, | |||
392 | err_printf(m, "%s --- ringbuffer = 0x%08x\n", | 429 | err_printf(m, "%s --- ringbuffer = 0x%08x\n", |
393 | dev_priv->ring[i].name, | 430 | dev_priv->ring[i].name, |
394 | obj->gtt_offset); | 431 | obj->gtt_offset); |
395 | offset = 0; | 432 | print_error_obj(m, obj); |
396 | for (page = 0; page < obj->page_count; page++) { | ||
397 | for (elt = 0; elt < PAGE_SIZE/4; elt++) { | ||
398 | err_printf(m, "%08x : %08x\n", | ||
399 | offset, | ||
400 | obj->pages[page][elt]); | ||
401 | offset += 4; | ||
402 | } | ||
403 | } | ||
404 | } | 433 | } |
405 | 434 | ||
406 | if ((obj = error->ring[i].hws_page)) { | 435 | if ((obj = error->ring[i].hws_page)) { |
@@ -666,7 +695,8 @@ static u32 capture_pinned_bo(struct drm_i915_error_buffer *err, | |||
666 | * It's only a small step better than a random number in its current form. | 695 | * It's only a small step better than a random number in its current form. |
667 | */ | 696 | */ |
668 | static uint32_t i915_error_generate_code(struct drm_i915_private *dev_priv, | 697 | static uint32_t i915_error_generate_code(struct drm_i915_private *dev_priv, |
669 | struct drm_i915_error_state *error) | 698 | struct drm_i915_error_state *error, |
699 | int *ring_id) | ||
670 | { | 700 | { |
671 | uint32_t error_code = 0; | 701 | uint32_t error_code = 0; |
672 | int i; | 702 | int i; |
@@ -676,9 +706,14 @@ static uint32_t i915_error_generate_code(struct drm_i915_private *dev_priv, | |||
676 | * synchronization commands which almost always appear in the case | 706 | * synchronization commands which almost always appear in the case |
677 | * strictly a client bug. Use instdone to differentiate those some. | 707 | * strictly a client bug. Use instdone to differentiate those some. |
678 | */ | 708 | */ |
679 | for (i = 0; i < I915_NUM_RINGS; i++) | 709 | for (i = 0; i < I915_NUM_RINGS; i++) { |
680 | if (error->ring[i].hangcheck_action == HANGCHECK_HUNG) | 710 | if (error->ring[i].hangcheck_action == HANGCHECK_HUNG) { |
711 | if (ring_id) | ||
712 | *ring_id = i; | ||
713 | |||
681 | return error->ring[i].ipehr ^ error->ring[i].instdone; | 714 | return error->ring[i].ipehr ^ error->ring[i].instdone; |
715 | } | ||
716 | } | ||
682 | 717 | ||
683 | return error_code; | 718 | return error_code; |
684 | } | 719 | } |
@@ -716,87 +751,6 @@ static void i915_gem_record_fences(struct drm_device *dev, | |||
716 | } | 751 | } |
717 | } | 752 | } |
718 | 753 | ||
719 | /* This assumes all batchbuffers are executed from the PPGTT. It might have to | ||
720 | * change in the future. */ | ||
721 | static bool is_active_vm(struct i915_address_space *vm, | ||
722 | struct intel_ring_buffer *ring) | ||
723 | { | ||
724 | struct drm_device *dev = vm->dev; | ||
725 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
726 | struct i915_hw_ppgtt *ppgtt; | ||
727 | |||
728 | if (INTEL_INFO(dev)->gen < 7) | ||
729 | return i915_is_ggtt(vm); | ||
730 | |||
731 | /* FIXME: This ignores that the global gtt vm is also on this list. */ | ||
732 | ppgtt = container_of(vm, struct i915_hw_ppgtt, base); | ||
733 | |||
734 | if (INTEL_INFO(dev)->gen >= 8) { | ||
735 | u64 pdp0 = (u64)I915_READ(GEN8_RING_PDP_UDW(ring, 0)) << 32; | ||
736 | pdp0 |= I915_READ(GEN8_RING_PDP_LDW(ring, 0)); | ||
737 | return pdp0 == ppgtt->pd_dma_addr[0]; | ||
738 | } else { | ||
739 | u32 pp_db; | ||
740 | pp_db = I915_READ(RING_PP_DIR_BASE(ring)); | ||
741 | return (pp_db >> 10) == ppgtt->pd_offset; | ||
742 | } | ||
743 | } | ||
744 | |||
745 | static struct drm_i915_error_object * | ||
746 | i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, | ||
747 | struct intel_ring_buffer *ring) | ||
748 | { | ||
749 | struct i915_address_space *vm; | ||
750 | struct i915_vma *vma; | ||
751 | struct drm_i915_gem_object *obj; | ||
752 | bool found_active = false; | ||
753 | u32 seqno; | ||
754 | |||
755 | if (!ring->get_seqno) | ||
756 | return NULL; | ||
757 | |||
758 | if (HAS_BROKEN_CS_TLB(dev_priv->dev)) { | ||
759 | u32 acthd = I915_READ(ACTHD); | ||
760 | |||
761 | if (WARN_ON(ring->id != RCS)) | ||
762 | return NULL; | ||
763 | |||
764 | obj = ring->scratch.obj; | ||
765 | if (obj != NULL && | ||
766 | acthd >= i915_gem_obj_ggtt_offset(obj) && | ||
767 | acthd < i915_gem_obj_ggtt_offset(obj) + obj->base.size) | ||
768 | return i915_error_ggtt_object_create(dev_priv, obj); | ||
769 | } | ||
770 | |||
771 | seqno = ring->get_seqno(ring, false); | ||
772 | list_for_each_entry(vm, &dev_priv->vm_list, global_link) { | ||
773 | if (!is_active_vm(vm, ring)) | ||
774 | continue; | ||
775 | |||
776 | found_active = true; | ||
777 | |||
778 | list_for_each_entry(vma, &vm->active_list, mm_list) { | ||
779 | obj = vma->obj; | ||
780 | if (obj->ring != ring) | ||
781 | continue; | ||
782 | |||
783 | if (i915_seqno_passed(seqno, obj->last_read_seqno)) | ||
784 | continue; | ||
785 | |||
786 | if ((obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) == 0) | ||
787 | continue; | ||
788 | |||
789 | /* We need to copy these to an anonymous buffer as the simplest | ||
790 | * method to avoid being overwritten by userspace. | ||
791 | */ | ||
792 | return i915_error_object_create(dev_priv, obj, vm); | ||
793 | } | ||
794 | } | ||
795 | |||
796 | WARN_ON(!found_active); | ||
797 | return NULL; | ||
798 | } | ||
799 | |||
800 | static void i915_record_ring_state(struct drm_device *dev, | 754 | static void i915_record_ring_state(struct drm_device *dev, |
801 | struct intel_ring_buffer *ring, | 755 | struct intel_ring_buffer *ring, |
802 | struct drm_i915_error_ring *ering) | 756 | struct drm_i915_error_ring *ering) |
@@ -945,8 +899,39 @@ static void i915_gem_record_rings(struct drm_device *dev, | |||
945 | 899 | ||
946 | i915_record_ring_state(dev, ring, &error->ring[i]); | 900 | i915_record_ring_state(dev, ring, &error->ring[i]); |
947 | 901 | ||
948 | error->ring[i].batchbuffer = | 902 | error->ring[i].pid = -1; |
949 | i915_error_first_batchbuffer(dev_priv, ring); | 903 | request = i915_gem_find_active_request(ring); |
904 | if (request) { | ||
905 | /* We need to copy these to an anonymous buffer | ||
906 | * as the simplest method to avoid being overwritten | ||
907 | * by userspace. | ||
908 | */ | ||
909 | error->ring[i].batchbuffer = | ||
910 | i915_error_object_create(dev_priv, | ||
911 | request->batch_obj, | ||
912 | request->ctx ? | ||
913 | request->ctx->vm : | ||
914 | &dev_priv->gtt.base); | ||
915 | |||
916 | if (HAS_BROKEN_CS_TLB(dev_priv->dev) && | ||
917 | ring->scratch.obj) | ||
918 | error->ring[i].wa_batchbuffer = | ||
919 | i915_error_ggtt_object_create(dev_priv, | ||
920 | ring->scratch.obj); | ||
921 | |||
922 | if (request->file_priv) { | ||
923 | struct task_struct *task; | ||
924 | |||
925 | rcu_read_lock(); | ||
926 | task = pid_task(request->file_priv->file->pid, | ||
927 | PIDTYPE_PID); | ||
928 | if (task) { | ||
929 | strcpy(error->ring[i].comm, task->comm); | ||
930 | error->ring[i].pid = task->pid; | ||
931 | } | ||
932 | rcu_read_unlock(); | ||
933 | } | ||
934 | } | ||
950 | 935 | ||
951 | error->ring[i].ringbuffer = | 936 | error->ring[i].ringbuffer = |
952 | i915_error_ggtt_object_create(dev_priv, ring->obj); | 937 | i915_error_ggtt_object_create(dev_priv, ring->obj); |
@@ -1113,6 +1098,40 @@ static void i915_capture_reg_state(struct drm_i915_private *dev_priv, | |||
1113 | i915_get_extra_instdone(dev, error->extra_instdone); | 1098 | i915_get_extra_instdone(dev, error->extra_instdone); |
1114 | } | 1099 | } |
1115 | 1100 | ||
1101 | static void i915_error_capture_msg(struct drm_device *dev, | ||
1102 | struct drm_i915_error_state *error, | ||
1103 | bool wedged, | ||
1104 | const char *error_msg) | ||
1105 | { | ||
1106 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1107 | u32 ecode; | ||
1108 | int ring_id = -1, len; | ||
1109 | |||
1110 | ecode = i915_error_generate_code(dev_priv, error, &ring_id); | ||
1111 | |||
1112 | len = scnprintf(error->error_msg, sizeof(error->error_msg), | ||
1113 | "GPU HANG: ecode %d:0x%08x", ring_id, ecode); | ||
1114 | |||
1115 | if (ring_id != -1 && error->ring[ring_id].pid != -1) | ||
1116 | len += scnprintf(error->error_msg + len, | ||
1117 | sizeof(error->error_msg) - len, | ||
1118 | ", in %s [%d]", | ||
1119 | error->ring[ring_id].comm, | ||
1120 | error->ring[ring_id].pid); | ||
1121 | |||
1122 | scnprintf(error->error_msg + len, sizeof(error->error_msg) - len, | ||
1123 | ", reason: %s, action: %s", | ||
1124 | error_msg, | ||
1125 | wedged ? "reset" : "continue"); | ||
1126 | } | ||
1127 | |||
1128 | static void i915_capture_gen_state(struct drm_i915_private *dev_priv, | ||
1129 | struct drm_i915_error_state *error) | ||
1130 | { | ||
1131 | error->reset_count = i915_reset_count(&dev_priv->gpu_error); | ||
1132 | error->suspend_count = dev_priv->suspend_count; | ||
1133 | } | ||
1134 | |||
1116 | /** | 1135 | /** |
1117 | * i915_capture_error_state - capture an error record for later analysis | 1136 | * i915_capture_error_state - capture an error record for later analysis |
1118 | * @dev: drm device | 1137 | * @dev: drm device |
@@ -1122,19 +1141,13 @@ static void i915_capture_reg_state(struct drm_i915_private *dev_priv, | |||
1122 | * out a structure which becomes available in debugfs for user level tools | 1141 | * out a structure which becomes available in debugfs for user level tools |
1123 | * to pick up. | 1142 | * to pick up. |
1124 | */ | 1143 | */ |
1125 | void i915_capture_error_state(struct drm_device *dev) | 1144 | void i915_capture_error_state(struct drm_device *dev, bool wedged, |
1145 | const char *error_msg) | ||
1126 | { | 1146 | { |
1127 | static bool warned; | 1147 | static bool warned; |
1128 | struct drm_i915_private *dev_priv = dev->dev_private; | 1148 | struct drm_i915_private *dev_priv = dev->dev_private; |
1129 | struct drm_i915_error_state *error; | 1149 | struct drm_i915_error_state *error; |
1130 | unsigned long flags; | 1150 | unsigned long flags; |
1131 | uint32_t ecode; | ||
1132 | |||
1133 | spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); | ||
1134 | error = dev_priv->gpu_error.first_error; | ||
1135 | spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); | ||
1136 | if (error) | ||
1137 | return; | ||
1138 | 1151 | ||
1139 | /* Account for pipe specific data like PIPE*STAT */ | 1152 | /* Account for pipe specific data like PIPE*STAT */ |
1140 | error = kzalloc(sizeof(*error), GFP_ATOMIC); | 1153 | error = kzalloc(sizeof(*error), GFP_ATOMIC); |
@@ -1143,30 +1156,22 @@ void i915_capture_error_state(struct drm_device *dev) | |||
1143 | return; | 1156 | return; |
1144 | } | 1157 | } |
1145 | 1158 | ||
1146 | DRM_INFO("GPU crash dump saved to /sys/class/drm/card%d/error\n", | ||
1147 | dev->primary->index); | ||
1148 | kref_init(&error->ref); | 1159 | kref_init(&error->ref); |
1149 | 1160 | ||
1161 | i915_capture_gen_state(dev_priv, error); | ||
1150 | i915_capture_reg_state(dev_priv, error); | 1162 | i915_capture_reg_state(dev_priv, error); |
1151 | i915_gem_capture_buffers(dev_priv, error); | 1163 | i915_gem_capture_buffers(dev_priv, error); |
1152 | i915_gem_record_fences(dev, error); | 1164 | i915_gem_record_fences(dev, error); |
1153 | i915_gem_record_rings(dev, error); | 1165 | i915_gem_record_rings(dev, error); |
1154 | ecode = i915_error_generate_code(dev_priv, error); | ||
1155 | |||
1156 | if (!warned) { | ||
1157 | DRM_INFO("GPU HANG [%x]\n", ecode); | ||
1158 | DRM_INFO("GPU hangs can indicate a bug anywhere in the entire gfx stack, including userspace.\n"); | ||
1159 | DRM_INFO("Please file a _new_ bug report on bugs.freedesktop.org against DRI -> DRM/Intel\n"); | ||
1160 | DRM_INFO("drm/i915 developers can then reassign to the right component if it's not a kernel issue.\n"); | ||
1161 | DRM_INFO("The gpu crash dump is required to analyze gpu hangs, so please always attach it.\n"); | ||
1162 | warned = true; | ||
1163 | } | ||
1164 | 1166 | ||
1165 | do_gettimeofday(&error->time); | 1167 | do_gettimeofday(&error->time); |
1166 | 1168 | ||
1167 | error->overlay = intel_overlay_capture_error_state(dev); | 1169 | error->overlay = intel_overlay_capture_error_state(dev); |
1168 | error->display = intel_display_capture_error_state(dev); | 1170 | error->display = intel_display_capture_error_state(dev); |
1169 | 1171 | ||
1172 | i915_error_capture_msg(dev, error, wedged, error_msg); | ||
1173 | DRM_INFO("%s\n", error->error_msg); | ||
1174 | |||
1170 | spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); | 1175 | spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); |
1171 | if (dev_priv->gpu_error.first_error == NULL) { | 1176 | if (dev_priv->gpu_error.first_error == NULL) { |
1172 | dev_priv->gpu_error.first_error = error; | 1177 | dev_priv->gpu_error.first_error = error; |
@@ -1174,8 +1179,19 @@ void i915_capture_error_state(struct drm_device *dev) | |||
1174 | } | 1179 | } |
1175 | spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); | 1180 | spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); |
1176 | 1181 | ||
1177 | if (error) | 1182 | if (error) { |
1178 | i915_error_state_free(&error->ref); | 1183 | i915_error_state_free(&error->ref); |
1184 | return; | ||
1185 | } | ||
1186 | |||
1187 | if (!warned) { | ||
1188 | DRM_INFO("GPU hangs can indicate a bug anywhere in the entire gfx stack, including userspace.\n"); | ||
1189 | DRM_INFO("Please file a _new_ bug report on bugs.freedesktop.org against DRI -> DRM/Intel\n"); | ||
1190 | DRM_INFO("drm/i915 developers can then reassign to the right component if it's not a kernel issue.\n"); | ||
1191 | DRM_INFO("The gpu crash dump is required to analyze gpu hangs, so please always attach it.\n"); | ||
1192 | DRM_INFO("GPU crash dump saved to /sys/class/drm/card%d/error\n", dev->primary->index); | ||
1193 | warned = true; | ||
1194 | } | ||
1179 | } | 1195 | } |
1180 | 1196 | ||
1181 | void i915_error_state_get(struct drm_device *dev, | 1197 | void i915_error_state_get(struct drm_device *dev, |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index f68aee31e565..be2713f12e08 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -387,16 +387,15 @@ static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, | |||
387 | * | 387 | * |
388 | * Returns the previous state of underrun reporting. | 388 | * Returns the previous state of underrun reporting. |
389 | */ | 389 | */ |
390 | bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, | 390 | bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, |
391 | enum pipe pipe, bool enable) | 391 | enum pipe pipe, bool enable) |
392 | { | 392 | { |
393 | struct drm_i915_private *dev_priv = dev->dev_private; | 393 | struct drm_i915_private *dev_priv = dev->dev_private; |
394 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | 394 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; |
395 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 395 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
396 | unsigned long flags; | ||
397 | bool ret; | 396 | bool ret; |
398 | 397 | ||
399 | spin_lock_irqsave(&dev_priv->irq_lock, flags); | 398 | assert_spin_locked(&dev_priv->irq_lock); |
400 | 399 | ||
401 | ret = !intel_crtc->cpu_fifo_underrun_disabled; | 400 | ret = !intel_crtc->cpu_fifo_underrun_disabled; |
402 | 401 | ||
@@ -415,7 +414,20 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, | |||
415 | broadwell_set_fifo_underrun_reporting(dev, pipe, enable); | 414 | broadwell_set_fifo_underrun_reporting(dev, pipe, enable); |
416 | 415 | ||
417 | done: | 416 | done: |
417 | return ret; | ||
418 | } | ||
419 | |||
420 | bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, | ||
421 | enum pipe pipe, bool enable) | ||
422 | { | ||
423 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
424 | unsigned long flags; | ||
425 | bool ret; | ||
426 | |||
427 | spin_lock_irqsave(&dev_priv->irq_lock, flags); | ||
428 | ret = __intel_set_cpu_fifo_underrun_reporting(dev, pipe, enable); | ||
418 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); | 429 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); |
430 | |||
419 | return ret; | 431 | return ret; |
420 | } | 432 | } |
421 | 433 | ||
@@ -482,7 +494,7 @@ done: | |||
482 | } | 494 | } |
483 | 495 | ||
484 | 496 | ||
485 | void | 497 | static void |
486 | __i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, | 498 | __i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, |
487 | u32 enable_mask, u32 status_mask) | 499 | u32 enable_mask, u32 status_mask) |
488 | { | 500 | { |
@@ -506,7 +518,7 @@ __i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, | |||
506 | POSTING_READ(reg); | 518 | POSTING_READ(reg); |
507 | } | 519 | } |
508 | 520 | ||
509 | void | 521 | static void |
510 | __i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, | 522 | __i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, |
511 | u32 enable_mask, u32 status_mask) | 523 | u32 enable_mask, u32 status_mask) |
512 | { | 524 | { |
@@ -1296,8 +1308,8 @@ static void snb_gt_irq_handler(struct drm_device *dev, | |||
1296 | if (gt_iir & (GT_BLT_CS_ERROR_INTERRUPT | | 1308 | if (gt_iir & (GT_BLT_CS_ERROR_INTERRUPT | |
1297 | GT_BSD_CS_ERROR_INTERRUPT | | 1309 | GT_BSD_CS_ERROR_INTERRUPT | |
1298 | GT_RENDER_CS_MASTER_ERROR_INTERRUPT)) { | 1310 | GT_RENDER_CS_MASTER_ERROR_INTERRUPT)) { |
1299 | DRM_ERROR("GT error interrupt 0x%08x\n", gt_iir); | 1311 | i915_handle_error(dev, false, "GT error interrupt 0x%08x", |
1300 | i915_handle_error(dev, false); | 1312 | gt_iir); |
1301 | } | 1313 | } |
1302 | 1314 | ||
1303 | if (gt_iir & GT_PARITY_ERROR(dev)) | 1315 | if (gt_iir & GT_PARITY_ERROR(dev)) |
@@ -1544,8 +1556,9 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) | |||
1544 | notify_ring(dev_priv->dev, &dev_priv->ring[VECS]); | 1556 | notify_ring(dev_priv->dev, &dev_priv->ring[VECS]); |
1545 | 1557 | ||
1546 | if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT) { | 1558 | if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT) { |
1547 | DRM_ERROR("VEBOX CS error interrupt 0x%08x\n", pm_iir); | 1559 | i915_handle_error(dev_priv->dev, false, |
1548 | i915_handle_error(dev_priv->dev, false); | 1560 | "VEBOX CS error interrupt 0x%08x", |
1561 | pm_iir); | ||
1549 | } | 1562 | } |
1550 | } | 1563 | } |
1551 | } | 1564 | } |
@@ -1865,7 +1878,7 @@ static void ilk_display_irq_handler(struct drm_device *dev, u32 de_iir) | |||
1865 | static void ivb_display_irq_handler(struct drm_device *dev, u32 de_iir) | 1878 | static void ivb_display_irq_handler(struct drm_device *dev, u32 de_iir) |
1866 | { | 1879 | { |
1867 | struct drm_i915_private *dev_priv = dev->dev_private; | 1880 | struct drm_i915_private *dev_priv = dev->dev_private; |
1868 | enum pipe i; | 1881 | enum pipe pipe; |
1869 | 1882 | ||
1870 | if (de_iir & DE_ERR_INT_IVB) | 1883 | if (de_iir & DE_ERR_INT_IVB) |
1871 | ivb_err_int_handler(dev); | 1884 | ivb_err_int_handler(dev); |
@@ -1876,14 +1889,14 @@ static void ivb_display_irq_handler(struct drm_device *dev, u32 de_iir) | |||
1876 | if (de_iir & DE_GSE_IVB) | 1889 | if (de_iir & DE_GSE_IVB) |
1877 | intel_opregion_asle_intr(dev); | 1890 | intel_opregion_asle_intr(dev); |
1878 | 1891 | ||
1879 | for_each_pipe(i) { | 1892 | for_each_pipe(pipe) { |
1880 | if (de_iir & (DE_PIPE_VBLANK_IVB(i))) | 1893 | if (de_iir & (DE_PIPE_VBLANK_IVB(pipe))) |
1881 | drm_handle_vblank(dev, i); | 1894 | drm_handle_vblank(dev, pipe); |
1882 | 1895 | ||
1883 | /* plane/pipes map 1:1 on ilk+ */ | 1896 | /* plane/pipes map 1:1 on ilk+ */ |
1884 | if (de_iir & DE_PLANE_FLIP_DONE_IVB(i)) { | 1897 | if (de_iir & DE_PLANE_FLIP_DONE_IVB(pipe)) { |
1885 | intel_prepare_page_flip(dev, i); | 1898 | intel_prepare_page_flip(dev, pipe); |
1886 | intel_finish_page_flip_plane(dev, i); | 1899 | intel_finish_page_flip_plane(dev, pipe); |
1887 | } | 1900 | } |
1888 | } | 1901 | } |
1889 | 1902 | ||
@@ -2277,11 +2290,18 @@ static void i915_report_and_clear_eir(struct drm_device *dev) | |||
2277 | * so userspace knows something bad happened (should trigger collection | 2290 | * so userspace knows something bad happened (should trigger collection |
2278 | * of a ring dump etc.). | 2291 | * of a ring dump etc.). |
2279 | */ | 2292 | */ |
2280 | void i915_handle_error(struct drm_device *dev, bool wedged) | 2293 | void i915_handle_error(struct drm_device *dev, bool wedged, |
2294 | const char *fmt, ...) | ||
2281 | { | 2295 | { |
2282 | struct drm_i915_private *dev_priv = dev->dev_private; | 2296 | struct drm_i915_private *dev_priv = dev->dev_private; |
2297 | va_list args; | ||
2298 | char error_msg[80]; | ||
2299 | |||
2300 | va_start(args, fmt); | ||
2301 | vscnprintf(error_msg, sizeof(error_msg), fmt, args); | ||
2302 | va_end(args); | ||
2283 | 2303 | ||
2284 | i915_capture_error_state(dev); | 2304 | i915_capture_error_state(dev, wedged, error_msg); |
2285 | i915_report_and_clear_eir(dev); | 2305 | i915_report_and_clear_eir(dev); |
2286 | 2306 | ||
2287 | if (wedged) { | 2307 | if (wedged) { |
@@ -2584,9 +2604,9 @@ ring_stuck(struct intel_ring_buffer *ring, u32 acthd) | |||
2584 | */ | 2604 | */ |
2585 | tmp = I915_READ_CTL(ring); | 2605 | tmp = I915_READ_CTL(ring); |
2586 | if (tmp & RING_WAIT) { | 2606 | if (tmp & RING_WAIT) { |
2587 | DRM_ERROR("Kicking stuck wait on %s\n", | 2607 | i915_handle_error(dev, false, |
2588 | ring->name); | 2608 | "Kicking stuck wait on %s", |
2589 | i915_handle_error(dev, false); | 2609 | ring->name); |
2590 | I915_WRITE_CTL(ring, tmp); | 2610 | I915_WRITE_CTL(ring, tmp); |
2591 | return HANGCHECK_KICK; | 2611 | return HANGCHECK_KICK; |
2592 | } | 2612 | } |
@@ -2596,9 +2616,9 @@ ring_stuck(struct intel_ring_buffer *ring, u32 acthd) | |||
2596 | default: | 2616 | default: |
2597 | return HANGCHECK_HUNG; | 2617 | return HANGCHECK_HUNG; |
2598 | case 1: | 2618 | case 1: |
2599 | DRM_ERROR("Kicking stuck semaphore on %s\n", | 2619 | i915_handle_error(dev, false, |
2600 | ring->name); | 2620 | "Kicking stuck semaphore on %s", |
2601 | i915_handle_error(dev, false); | 2621 | ring->name); |
2602 | I915_WRITE_CTL(ring, tmp); | 2622 | I915_WRITE_CTL(ring, tmp); |
2603 | return HANGCHECK_KICK; | 2623 | return HANGCHECK_KICK; |
2604 | case 0: | 2624 | case 0: |
@@ -2720,7 +2740,7 @@ static void i915_hangcheck_elapsed(unsigned long data) | |||
2720 | } | 2740 | } |
2721 | 2741 | ||
2722 | if (rings_hung) | 2742 | if (rings_hung) |
2723 | return i915_handle_error(dev, true); | 2743 | return i915_handle_error(dev, true, "Ring hung"); |
2724 | 2744 | ||
2725 | if (busy_count) | 2745 | if (busy_count) |
2726 | /* Reset timer case chip hangs without another request | 2746 | /* Reset timer case chip hangs without another request |
@@ -3016,44 +3036,113 @@ static int ironlake_irq_postinstall(struct drm_device *dev) | |||
3016 | return 0; | 3036 | return 0; |
3017 | } | 3037 | } |
3018 | 3038 | ||
3039 | static void valleyview_display_irqs_install(struct drm_i915_private *dev_priv) | ||
3040 | { | ||
3041 | u32 pipestat_mask; | ||
3042 | u32 iir_mask; | ||
3043 | |||
3044 | pipestat_mask = PIPESTAT_INT_STATUS_MASK | | ||
3045 | PIPE_FIFO_UNDERRUN_STATUS; | ||
3046 | |||
3047 | I915_WRITE(PIPESTAT(PIPE_A), pipestat_mask); | ||
3048 | I915_WRITE(PIPESTAT(PIPE_B), pipestat_mask); | ||
3049 | POSTING_READ(PIPESTAT(PIPE_A)); | ||
3050 | |||
3051 | pipestat_mask = PLANE_FLIP_DONE_INT_STATUS_VLV | | ||
3052 | PIPE_CRC_DONE_INTERRUPT_STATUS; | ||
3053 | |||
3054 | i915_enable_pipestat(dev_priv, PIPE_A, pipestat_mask | | ||
3055 | PIPE_GMBUS_INTERRUPT_STATUS); | ||
3056 | i915_enable_pipestat(dev_priv, PIPE_B, pipestat_mask); | ||
3057 | |||
3058 | iir_mask = I915_DISPLAY_PORT_INTERRUPT | | ||
3059 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | | ||
3060 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; | ||
3061 | dev_priv->irq_mask &= ~iir_mask; | ||
3062 | |||
3063 | I915_WRITE(VLV_IIR, iir_mask); | ||
3064 | I915_WRITE(VLV_IIR, iir_mask); | ||
3065 | I915_WRITE(VLV_IMR, dev_priv->irq_mask); | ||
3066 | I915_WRITE(VLV_IER, ~dev_priv->irq_mask); | ||
3067 | POSTING_READ(VLV_IER); | ||
3068 | } | ||
3069 | |||
3070 | static void valleyview_display_irqs_uninstall(struct drm_i915_private *dev_priv) | ||
3071 | { | ||
3072 | u32 pipestat_mask; | ||
3073 | u32 iir_mask; | ||
3074 | |||
3075 | iir_mask = I915_DISPLAY_PORT_INTERRUPT | | ||
3076 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | | ||
3077 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; | ||
3078 | |||
3079 | dev_priv->irq_mask |= iir_mask; | ||
3080 | I915_WRITE(VLV_IER, ~dev_priv->irq_mask); | ||
3081 | I915_WRITE(VLV_IMR, dev_priv->irq_mask); | ||
3082 | I915_WRITE(VLV_IIR, iir_mask); | ||
3083 | I915_WRITE(VLV_IIR, iir_mask); | ||
3084 | POSTING_READ(VLV_IIR); | ||
3085 | |||
3086 | pipestat_mask = PLANE_FLIP_DONE_INT_STATUS_VLV | | ||
3087 | PIPE_CRC_DONE_INTERRUPT_STATUS; | ||
3088 | |||
3089 | i915_disable_pipestat(dev_priv, PIPE_A, pipestat_mask | | ||
3090 | PIPE_GMBUS_INTERRUPT_STATUS); | ||
3091 | i915_disable_pipestat(dev_priv, PIPE_B, pipestat_mask); | ||
3092 | |||
3093 | pipestat_mask = PIPESTAT_INT_STATUS_MASK | | ||
3094 | PIPE_FIFO_UNDERRUN_STATUS; | ||
3095 | I915_WRITE(PIPESTAT(PIPE_A), pipestat_mask); | ||
3096 | I915_WRITE(PIPESTAT(PIPE_B), pipestat_mask); | ||
3097 | POSTING_READ(PIPESTAT(PIPE_A)); | ||
3098 | } | ||
3099 | |||
3100 | void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv) | ||
3101 | { | ||
3102 | assert_spin_locked(&dev_priv->irq_lock); | ||
3103 | |||
3104 | if (dev_priv->display_irqs_enabled) | ||
3105 | return; | ||
3106 | |||
3107 | dev_priv->display_irqs_enabled = true; | ||
3108 | |||
3109 | if (dev_priv->dev->irq_enabled) | ||
3110 | valleyview_display_irqs_install(dev_priv); | ||
3111 | } | ||
3112 | |||
3113 | void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv) | ||
3114 | { | ||
3115 | assert_spin_locked(&dev_priv->irq_lock); | ||
3116 | |||
3117 | if (!dev_priv->display_irqs_enabled) | ||
3118 | return; | ||
3119 | |||
3120 | dev_priv->display_irqs_enabled = false; | ||
3121 | |||
3122 | if (dev_priv->dev->irq_enabled) | ||
3123 | valleyview_display_irqs_uninstall(dev_priv); | ||
3124 | } | ||
3125 | |||
3019 | static int valleyview_irq_postinstall(struct drm_device *dev) | 3126 | static int valleyview_irq_postinstall(struct drm_device *dev) |
3020 | { | 3127 | { |
3021 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 3128 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
3022 | u32 enable_mask; | ||
3023 | u32 pipestat_enable = PLANE_FLIP_DONE_INT_STATUS_VLV | | ||
3024 | PIPE_CRC_DONE_INTERRUPT_STATUS; | ||
3025 | unsigned long irqflags; | 3129 | unsigned long irqflags; |
3026 | 3130 | ||
3027 | enable_mask = I915_DISPLAY_PORT_INTERRUPT; | 3131 | dev_priv->irq_mask = ~0; |
3028 | enable_mask |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | | ||
3029 | I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | | ||
3030 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | | ||
3031 | I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; | ||
3032 | |||
3033 | /* | ||
3034 | *Leave vblank interrupts masked initially. enable/disable will | ||
3035 | * toggle them based on usage. | ||
3036 | */ | ||
3037 | dev_priv->irq_mask = (~enable_mask) | | ||
3038 | I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | | ||
3039 | I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; | ||
3040 | 3132 | ||
3041 | I915_WRITE(PORT_HOTPLUG_EN, 0); | 3133 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
3042 | POSTING_READ(PORT_HOTPLUG_EN); | 3134 | POSTING_READ(PORT_HOTPLUG_EN); |
3043 | 3135 | ||
3044 | I915_WRITE(VLV_IMR, dev_priv->irq_mask); | 3136 | I915_WRITE(VLV_IMR, dev_priv->irq_mask); |
3045 | I915_WRITE(VLV_IER, enable_mask); | 3137 | I915_WRITE(VLV_IER, ~dev_priv->irq_mask); |
3046 | I915_WRITE(VLV_IIR, 0xffffffff); | 3138 | I915_WRITE(VLV_IIR, 0xffffffff); |
3047 | I915_WRITE(PIPESTAT(0), 0xffff); | ||
3048 | I915_WRITE(PIPESTAT(1), 0xffff); | ||
3049 | POSTING_READ(VLV_IER); | 3139 | POSTING_READ(VLV_IER); |
3050 | 3140 | ||
3051 | /* Interrupt setup is already guaranteed to be single-threaded, this is | 3141 | /* Interrupt setup is already guaranteed to be single-threaded, this is |
3052 | * just to make the assert_spin_locked check happy. */ | 3142 | * just to make the assert_spin_locked check happy. */ |
3053 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 3143 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
3054 | i915_enable_pipestat(dev_priv, PIPE_A, pipestat_enable); | 3144 | if (dev_priv->display_irqs_enabled) |
3055 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); | 3145 | valleyview_display_irqs_install(dev_priv); |
3056 | i915_enable_pipestat(dev_priv, PIPE_B, pipestat_enable); | ||
3057 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 3146 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
3058 | 3147 | ||
3059 | I915_WRITE(VLV_IIR, 0xffffffff); | 3148 | I915_WRITE(VLV_IIR, 0xffffffff); |
@@ -3184,6 +3273,7 @@ static void gen8_irq_uninstall(struct drm_device *dev) | |||
3184 | static void valleyview_irq_uninstall(struct drm_device *dev) | 3273 | static void valleyview_irq_uninstall(struct drm_device *dev) |
3185 | { | 3274 | { |
3186 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 3275 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
3276 | unsigned long irqflags; | ||
3187 | int pipe; | 3277 | int pipe; |
3188 | 3278 | ||
3189 | if (!dev_priv) | 3279 | if (!dev_priv) |
@@ -3197,8 +3287,14 @@ static void valleyview_irq_uninstall(struct drm_device *dev) | |||
3197 | I915_WRITE(HWSTAM, 0xffffffff); | 3287 | I915_WRITE(HWSTAM, 0xffffffff); |
3198 | I915_WRITE(PORT_HOTPLUG_EN, 0); | 3288 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
3199 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); | 3289 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); |
3200 | for_each_pipe(pipe) | 3290 | |
3201 | I915_WRITE(PIPESTAT(pipe), 0xffff); | 3291 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
3292 | if (dev_priv->display_irqs_enabled) | ||
3293 | valleyview_display_irqs_uninstall(dev_priv); | ||
3294 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
3295 | |||
3296 | dev_priv->irq_mask = 0; | ||
3297 | |||
3202 | I915_WRITE(VLV_IIR, 0xffffffff); | 3298 | I915_WRITE(VLV_IIR, 0xffffffff); |
3203 | I915_WRITE(VLV_IMR, 0xffffffff); | 3299 | I915_WRITE(VLV_IMR, 0xffffffff); |
3204 | I915_WRITE(VLV_IER, 0x0); | 3300 | I915_WRITE(VLV_IER, 0x0); |
@@ -3337,7 +3433,9 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) | |||
3337 | */ | 3433 | */ |
3338 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 3434 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
3339 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) | 3435 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) |
3340 | i915_handle_error(dev, false); | 3436 | i915_handle_error(dev, false, |
3437 | "Command parser error, iir 0x%08x", | ||
3438 | iir); | ||
3341 | 3439 | ||
3342 | for_each_pipe(pipe) { | 3440 | for_each_pipe(pipe) { |
3343 | int reg = PIPESTAT(pipe); | 3441 | int reg = PIPESTAT(pipe); |
@@ -3519,7 +3617,9 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) | |||
3519 | */ | 3617 | */ |
3520 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 3618 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
3521 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) | 3619 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) |
3522 | i915_handle_error(dev, false); | 3620 | i915_handle_error(dev, false, |
3621 | "Command parser error, iir 0x%08x", | ||
3622 | iir); | ||
3523 | 3623 | ||
3524 | for_each_pipe(pipe) { | 3624 | for_each_pipe(pipe) { |
3525 | int reg = PIPESTAT(pipe); | 3625 | int reg = PIPESTAT(pipe); |
@@ -3756,7 +3856,9 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) | |||
3756 | */ | 3856 | */ |
3757 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 3857 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
3758 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) | 3858 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) |
3759 | i915_handle_error(dev, false); | 3859 | i915_handle_error(dev, false, |
3860 | "Command parser error, iir 0x%08x", | ||
3861 | iir); | ||
3760 | 3862 | ||
3761 | for_each_pipe(pipe) { | 3863 | for_each_pipe(pipe) { |
3762 | int reg = PIPESTAT(pipe); | 3864 | int reg = PIPESTAT(pipe); |
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 3b482585c5ae..a66ffb652bee 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c | |||
@@ -48,6 +48,7 @@ struct i915_params i915 __read_mostly = { | |||
48 | .reset = true, | 48 | .reset = true, |
49 | .invert_brightness = 0, | 49 | .invert_brightness = 0, |
50 | .disable_display = 0, | 50 | .disable_display = 0, |
51 | .enable_cmd_parser = 0, | ||
51 | }; | 52 | }; |
52 | 53 | ||
53 | module_param_named(modeset, i915.modeset, int, 0400); | 54 | module_param_named(modeset, i915.modeset, int, 0400); |
@@ -157,3 +158,7 @@ MODULE_PARM_DESC(invert_brightness, | |||
157 | 158 | ||
158 | module_param_named(disable_display, i915.disable_display, bool, 0600); | 159 | module_param_named(disable_display, i915.disable_display, bool, 0600); |
159 | MODULE_PARM_DESC(disable_display, "Disable display (default: false)"); | 160 | MODULE_PARM_DESC(disable_display, "Disable display (default: false)"); |
161 | |||
162 | module_param_named(enable_cmd_parser, i915.enable_cmd_parser, int, 0600); | ||
163 | MODULE_PARM_DESC(enable_cmd_parser, | ||
164 | "Enable command parsing (1=enabled, 0=disabled [default])"); | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 2f564ce37d2c..146609ab42bb 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -175,6 +175,18 @@ | |||
175 | #define VGA_CR_DATA_CGA 0x3d5 | 175 | #define VGA_CR_DATA_CGA 0x3d5 |
176 | 176 | ||
177 | /* | 177 | /* |
178 | * Instruction field definitions used by the command parser | ||
179 | */ | ||
180 | #define INSTR_CLIENT_SHIFT 29 | ||
181 | #define INSTR_CLIENT_MASK 0xE0000000 | ||
182 | #define INSTR_MI_CLIENT 0x0 | ||
183 | #define INSTR_BC_CLIENT 0x2 | ||
184 | #define INSTR_RC_CLIENT 0x3 | ||
185 | #define INSTR_SUBCLIENT_SHIFT 27 | ||
186 | #define INSTR_SUBCLIENT_MASK 0x18000000 | ||
187 | #define INSTR_MEDIA_SUBCLIENT 0x2 | ||
188 | |||
189 | /* | ||
178 | * Memory interface instructions used by the kernel | 190 | * Memory interface instructions used by the kernel |
179 | */ | 191 | */ |
180 | #define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags)) | 192 | #define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags)) |
@@ -377,14 +389,30 @@ | |||
377 | #define DSPFREQSTAT_MASK (0x3 << DSPFREQSTAT_SHIFT) | 389 | #define DSPFREQSTAT_MASK (0x3 << DSPFREQSTAT_SHIFT) |
378 | #define DSPFREQGUAR_SHIFT 14 | 390 | #define DSPFREQGUAR_SHIFT 14 |
379 | #define DSPFREQGUAR_MASK (0x3 << DSPFREQGUAR_SHIFT) | 391 | #define DSPFREQGUAR_MASK (0x3 << DSPFREQGUAR_SHIFT) |
392 | |||
393 | /* See the PUNIT HAS v0.8 for the below bits */ | ||
394 | enum punit_power_well { | ||
395 | PUNIT_POWER_WELL_RENDER = 0, | ||
396 | PUNIT_POWER_WELL_MEDIA = 1, | ||
397 | PUNIT_POWER_WELL_DISP2D = 3, | ||
398 | PUNIT_POWER_WELL_DPIO_CMN_BC = 5, | ||
399 | PUNIT_POWER_WELL_DPIO_TX_B_LANES_01 = 6, | ||
400 | PUNIT_POWER_WELL_DPIO_TX_B_LANES_23 = 7, | ||
401 | PUNIT_POWER_WELL_DPIO_TX_C_LANES_01 = 8, | ||
402 | PUNIT_POWER_WELL_DPIO_TX_C_LANES_23 = 9, | ||
403 | PUNIT_POWER_WELL_DPIO_RX0 = 10, | ||
404 | PUNIT_POWER_WELL_DPIO_RX1 = 11, | ||
405 | |||
406 | PUNIT_POWER_WELL_NUM, | ||
407 | }; | ||
408 | |||
380 | #define PUNIT_REG_PWRGT_CTRL 0x60 | 409 | #define PUNIT_REG_PWRGT_CTRL 0x60 |
381 | #define PUNIT_REG_PWRGT_STATUS 0x61 | 410 | #define PUNIT_REG_PWRGT_STATUS 0x61 |
382 | #define PUNIT_CLK_GATE 1 | 411 | #define PUNIT_PWRGT_MASK(power_well) (3 << ((power_well) * 2)) |
383 | #define PUNIT_PWR_RESET 2 | 412 | #define PUNIT_PWRGT_PWR_ON(power_well) (0 << ((power_well) * 2)) |
384 | #define PUNIT_PWR_GATE 3 | 413 | #define PUNIT_PWRGT_CLK_GATE(power_well) (1 << ((power_well) * 2)) |
385 | #define RENDER_PWRGT (PUNIT_PWR_GATE << 0) | 414 | #define PUNIT_PWRGT_RESET(power_well) (2 << ((power_well) * 2)) |
386 | #define MEDIA_PWRGT (PUNIT_PWR_GATE << 2) | 415 | #define PUNIT_PWRGT_PWR_GATE(power_well) (3 << ((power_well) * 2)) |
387 | #define DISP2D_PWRGT (PUNIT_PWR_GATE << 6) | ||
388 | 416 | ||
389 | #define PUNIT_REG_GPU_LFM 0xd3 | 417 | #define PUNIT_REG_GPU_LFM 0xd3 |
390 | #define PUNIT_REG_GPU_FREQ_REQ 0xd4 | 418 | #define PUNIT_REG_GPU_FREQ_REQ 0xd4 |
@@ -798,7 +826,12 @@ | |||
798 | # define ASYNC_FLIP_PERF_DISABLE (1 << 14) | 826 | # define ASYNC_FLIP_PERF_DISABLE (1 << 14) |
799 | 827 | ||
800 | #define GEN6_GT_MODE 0x20d0 | 828 | #define GEN6_GT_MODE 0x20d0 |
801 | #define GEN6_GT_MODE_HI (1 << 9) | 829 | #define GEN7_GT_MODE 0x7008 |
830 | #define GEN6_WIZ_HASHING(hi, lo) (((hi) << 9) | ((lo) << 7)) | ||
831 | #define GEN6_WIZ_HASHING_8x8 GEN6_WIZ_HASHING(0, 0) | ||
832 | #define GEN6_WIZ_HASHING_8x4 GEN6_WIZ_HASHING(0, 1) | ||
833 | #define GEN6_WIZ_HASHING_16x4 GEN6_WIZ_HASHING(1, 0) | ||
834 | #define GEN6_WIZ_HASHING_MASK (GEN6_WIZ_HASHING(1, 1) << 16) | ||
802 | #define GEN6_TD_FOUR_ROW_DISPATCH_DISABLE (1 << 5) | 835 | #define GEN6_TD_FOUR_ROW_DISPATCH_DISABLE (1 << 5) |
803 | 836 | ||
804 | #define GFX_MODE 0x02520 | 837 | #define GFX_MODE 0x02520 |
@@ -944,6 +977,9 @@ | |||
944 | #define GEN6_BLITTER_LOCK_SHIFT 16 | 977 | #define GEN6_BLITTER_LOCK_SHIFT 16 |
945 | #define GEN6_BLITTER_FBC_NOTIFY (1<<3) | 978 | #define GEN6_BLITTER_FBC_NOTIFY (1<<3) |
946 | 979 | ||
980 | #define GEN6_RC_SLEEP_PSMI_CONTROL 0x2050 | ||
981 | #define GEN8_RC_SEMA_IDLE_MSG_DISABLE (1 << 12) | ||
982 | |||
947 | #define GEN6_BSD_SLEEP_PSMI_CONTROL 0x12050 | 983 | #define GEN6_BSD_SLEEP_PSMI_CONTROL 0x12050 |
948 | #define GEN6_BSD_SLEEP_MSG_DISABLE (1 << 0) | 984 | #define GEN6_BSD_SLEEP_MSG_DISABLE (1 << 0) |
949 | #define GEN6_BSD_SLEEP_FLUSH_DISABLE (1 << 2) | 985 | #define GEN6_BSD_SLEEP_FLUSH_DISABLE (1 << 2) |
@@ -1121,13 +1157,6 @@ | |||
1121 | #define FBC_REND_NUKE (1<<2) | 1157 | #define FBC_REND_NUKE (1<<2) |
1122 | #define FBC_REND_CACHE_CLEAN (1<<1) | 1158 | #define FBC_REND_CACHE_CLEAN (1<<1) |
1123 | 1159 | ||
1124 | #define _HSW_PIPE_SLICE_CHICKEN_1_A 0x420B0 | ||
1125 | #define _HSW_PIPE_SLICE_CHICKEN_1_B 0x420B4 | ||
1126 | #define HSW_BYPASS_FBC_QUEUE (1<<22) | ||
1127 | #define HSW_PIPE_SLICE_CHICKEN_1(pipe) _PIPE(pipe, + \ | ||
1128 | _HSW_PIPE_SLICE_CHICKEN_1_A, + \ | ||
1129 | _HSW_PIPE_SLICE_CHICKEN_1_B) | ||
1130 | |||
1131 | /* | 1160 | /* |
1132 | * GPIO regs | 1161 | * GPIO regs |
1133 | */ | 1162 | */ |
@@ -4140,7 +4169,8 @@ | |||
4140 | 4169 | ||
4141 | #define _CHICKEN_PIPESL_1_A 0x420b0 | 4170 | #define _CHICKEN_PIPESL_1_A 0x420b0 |
4142 | #define _CHICKEN_PIPESL_1_B 0x420b4 | 4171 | #define _CHICKEN_PIPESL_1_B 0x420b4 |
4143 | #define DPRS_MASK_VBLANK_SRD (1 << 0) | 4172 | #define HSW_FBCQ_DIS (1 << 22) |
4173 | #define BDW_DPRS_MASK_VBLANK_SRD (1 << 0) | ||
4144 | #define CHICKEN_PIPESL_1(pipe) _PIPE(pipe, _CHICKEN_PIPESL_1_A, _CHICKEN_PIPESL_1_B) | 4174 | #define CHICKEN_PIPESL_1(pipe) _PIPE(pipe, _CHICKEN_PIPESL_1_A, _CHICKEN_PIPESL_1_B) |
4145 | 4175 | ||
4146 | #define DISP_ARB_CTL 0x45000 | 4176 | #define DISP_ARB_CTL 0x45000 |
@@ -4164,7 +4194,7 @@ | |||
4164 | #define VLV_B0_WA_L3SQCREG1_VALUE 0x00D30000 | 4194 | #define VLV_B0_WA_L3SQCREG1_VALUE 0x00D30000 |
4165 | 4195 | ||
4166 | #define GEN7_L3CNTLREG1 0xB01C | 4196 | #define GEN7_L3CNTLREG1 0xB01C |
4167 | #define GEN7_WA_FOR_GEN7_L3_CONTROL 0x3C4FFF8C | 4197 | #define GEN7_WA_FOR_GEN7_L3_CONTROL 0x3C47FF8C |
4168 | #define GEN7_L3AGDIS (1<<19) | 4198 | #define GEN7_L3AGDIS (1<<19) |
4169 | 4199 | ||
4170 | #define GEN7_L3_CHICKEN_MODE_REGISTER 0xB030 | 4200 | #define GEN7_L3_CHICKEN_MODE_REGISTER 0xB030 |
@@ -4898,6 +4928,9 @@ | |||
4898 | #define GEN7_UCGCTL4 0x940c | 4928 | #define GEN7_UCGCTL4 0x940c |
4899 | #define GEN7_L3BANK2X_CLOCK_GATE_DISABLE (1<<25) | 4929 | #define GEN7_L3BANK2X_CLOCK_GATE_DISABLE (1<<25) |
4900 | 4930 | ||
4931 | #define GEN8_UCGCTL6 0x9430 | ||
4932 | #define GEN8_SDEUNIT_CLOCK_GATE_DISABLE (1<<14) | ||
4933 | |||
4901 | #define GEN6_RPNSWREQ 0xA008 | 4934 | #define GEN6_RPNSWREQ 0xA008 |
4902 | #define GEN6_TURBO_DISABLE (1<<31) | 4935 | #define GEN6_TURBO_DISABLE (1<<31) |
4903 | #define GEN6_FREQUENCY(x) ((x)<<25) | 4936 | #define GEN6_FREQUENCY(x) ((x)<<25) |
@@ -5043,6 +5076,10 @@ | |||
5043 | #define GEN7_SINGLE_SUBSCAN_DISPATCH_ENABLE (1<<10) | 5076 | #define GEN7_SINGLE_SUBSCAN_DISPATCH_ENABLE (1<<10) |
5044 | #define GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE (1<<3) | 5077 | #define GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE (1<<3) |
5045 | 5078 | ||
5079 | #define GEN8_ROW_CHICKEN 0xe4f0 | ||
5080 | #define PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE (1<<8) | ||
5081 | #define STALL_DOP_GATING_DISABLE (1<<5) | ||
5082 | |||
5046 | #define GEN7_ROW_CHICKEN2 0xe4f4 | 5083 | #define GEN7_ROW_CHICKEN2 0xe4f4 |
5047 | #define GEN7_ROW_CHICKEN2_GT2 0xf4f4 | 5084 | #define GEN7_ROW_CHICKEN2_GT2 0xf4f4 |
5048 | #define DOP_CLOCK_GATING_DISABLE (1<<0) | 5085 | #define DOP_CLOCK_GATING_DISABLE (1<<0) |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 86b95ca413d1..4867f4cc0938 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -599,14 +599,14 @@ parse_mipi(struct drm_i915_private *dev_priv, struct bdb_header *bdb) | |||
599 | { | 599 | { |
600 | struct bdb_mipi *mipi; | 600 | struct bdb_mipi *mipi; |
601 | 601 | ||
602 | mipi = find_section(bdb, BDB_MIPI); | 602 | mipi = find_section(bdb, BDB_MIPI_CONFIG); |
603 | if (!mipi) { | 603 | if (!mipi) { |
604 | DRM_DEBUG_KMS("No MIPI BDB found"); | 604 | DRM_DEBUG_KMS("No MIPI BDB found"); |
605 | return; | 605 | return; |
606 | } | 606 | } |
607 | 607 | ||
608 | /* XXX: add more info */ | 608 | /* XXX: add more info */ |
609 | dev_priv->vbt.dsi.panel_id = mipi->panel_id; | 609 | dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID; |
610 | } | 610 | } |
611 | 611 | ||
612 | static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, | 612 | static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, |
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index 282de5e9f39d..83b7629e4367 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h | |||
@@ -104,7 +104,8 @@ struct vbios_data { | |||
104 | #define BDB_LVDS_LFP_DATA 42 | 104 | #define BDB_LVDS_LFP_DATA 42 |
105 | #define BDB_LVDS_BACKLIGHT 43 | 105 | #define BDB_LVDS_BACKLIGHT 43 |
106 | #define BDB_LVDS_POWER 44 | 106 | #define BDB_LVDS_POWER 44 |
107 | #define BDB_MIPI 50 | 107 | #define BDB_MIPI_CONFIG 52 |
108 | #define BDB_MIPI_SEQUENCE 53 | ||
108 | #define BDB_SKIP 254 /* VBIOS private block, ignore */ | 109 | #define BDB_SKIP 254 /* VBIOS private block, ignore */ |
109 | 110 | ||
110 | struct bdb_general_features { | 111 | struct bdb_general_features { |
@@ -711,44 +712,159 @@ int intel_parse_bios(struct drm_device *dev); | |||
711 | #define DVO_PORT_DPD 9 | 712 | #define DVO_PORT_DPD 9 |
712 | #define DVO_PORT_DPA 10 | 713 | #define DVO_PORT_DPA 10 |
713 | 714 | ||
714 | /* MIPI DSI panel info */ | 715 | /* Block 52 contains MIPI Panel info |
715 | struct bdb_mipi { | 716 | * 6 such enteries will there. Index into correct |
716 | u16 panel_id; | 717 | * entery is based on the panel_index in #40 LFP |
717 | u16 bridge_revision; | 718 | */ |
718 | 719 | #define MAX_MIPI_CONFIGURATIONS 6 | |
719 | /* General params */ | ||
720 | u32 dithering:1; | ||
721 | u32 bpp_pixel_format:1; | ||
722 | u32 rsvd1:1; | ||
723 | u32 dphy_valid:1; | ||
724 | u32 resvd2:28; | ||
725 | 720 | ||
726 | u16 port_info; | 721 | #define MIPI_DSI_UNDEFINED_PANEL_ID 0 |
727 | u16 rsvd3:2; | 722 | #define MIPI_DSI_GENERIC_PANEL_ID 1 |
728 | u16 num_lanes:2; | ||
729 | u16 rsvd4:12; | ||
730 | 723 | ||
731 | /* DSI config */ | 724 | struct mipi_config { |
732 | u16 virt_ch_num:2; | 725 | u16 panel_id; |
733 | u16 vtm:2; | ||
734 | u16 rsvd5:12; | ||
735 | 726 | ||
736 | u32 dsi_clock; | 727 | /* General Params */ |
728 | u32 enable_dithering:1; | ||
729 | u32 rsvd1:1; | ||
730 | u32 is_bridge:1; | ||
731 | |||
732 | u32 panel_arch_type:2; | ||
733 | u32 is_cmd_mode:1; | ||
734 | |||
735 | #define NON_BURST_SYNC_PULSE 0x1 | ||
736 | #define NON_BURST_SYNC_EVENTS 0x2 | ||
737 | #define BURST_MODE 0x3 | ||
738 | u32 video_transfer_mode:2; | ||
739 | |||
740 | u32 cabc_supported:1; | ||
741 | u32 pwm_blc:1; | ||
742 | |||
743 | /* Bit 13:10 */ | ||
744 | #define PIXEL_FORMAT_RGB565 0x1 | ||
745 | #define PIXEL_FORMAT_RGB666 0x2 | ||
746 | #define PIXEL_FORMAT_RGB666_LOOSELY_PACKED 0x3 | ||
747 | #define PIXEL_FORMAT_RGB888 0x4 | ||
748 | u32 videomode_color_format:4; | ||
749 | |||
750 | /* Bit 15:14 */ | ||
751 | #define ENABLE_ROTATION_0 0x0 | ||
752 | #define ENABLE_ROTATION_90 0x1 | ||
753 | #define ENABLE_ROTATION_180 0x2 | ||
754 | #define ENABLE_ROTATION_270 0x3 | ||
755 | u32 rotation:2; | ||
756 | u32 bta_enabled:1; | ||
757 | u32 rsvd2:15; | ||
758 | |||
759 | /* 2 byte Port Description */ | ||
760 | #define DUAL_LINK_NOT_SUPPORTED 0 | ||
761 | #define DUAL_LINK_FRONT_BACK 1 | ||
762 | #define DUAL_LINK_PIXEL_ALT 2 | ||
763 | u16 dual_link:2; | ||
764 | u16 lane_cnt:2; | ||
765 | u16 rsvd3:12; | ||
766 | |||
767 | u16 rsvd4; | ||
768 | |||
769 | u8 rsvd5[5]; | ||
770 | u32 dsi_ddr_clk; | ||
737 | u32 bridge_ref_clk; | 771 | u32 bridge_ref_clk; |
738 | u16 rsvd_pwr; | ||
739 | 772 | ||
740 | /* Dphy Params */ | 773 | #define BYTE_CLK_SEL_20MHZ 0 |
741 | u32 prepare_cnt:5; | 774 | #define BYTE_CLK_SEL_10MHZ 1 |
742 | u32 rsvd6:3; | 775 | #define BYTE_CLK_SEL_5MHZ 2 |
776 | u8 byte_clk_sel:2; | ||
777 | |||
778 | u8 rsvd6:6; | ||
779 | |||
780 | /* DPHY Flags */ | ||
781 | u16 dphy_param_valid:1; | ||
782 | u16 eot_pkt_disabled:1; | ||
783 | u16 enable_clk_stop:1; | ||
784 | u16 rsvd7:13; | ||
785 | |||
786 | u32 hs_tx_timeout; | ||
787 | u32 lp_rx_timeout; | ||
788 | u32 turn_around_timeout; | ||
789 | u32 device_reset_timer; | ||
790 | u32 master_init_timer; | ||
791 | u32 dbi_bw_timer; | ||
792 | u32 lp_byte_clk_val; | ||
793 | |||
794 | /* 4 byte Dphy Params */ | ||
795 | u32 prepare_cnt:6; | ||
796 | u32 rsvd8:2; | ||
743 | u32 clk_zero_cnt:8; | 797 | u32 clk_zero_cnt:8; |
744 | u32 trail_cnt:5; | 798 | u32 trail_cnt:5; |
745 | u32 rsvd7:3; | 799 | u32 rsvd9:3; |
746 | u32 exit_zero_cnt:6; | 800 | u32 exit_zero_cnt:6; |
747 | u32 rsvd8:2; | 801 | u32 rsvd10:2; |
748 | 802 | ||
749 | u32 hl_switch_cnt; | ||
750 | u32 lp_byte_clk; | ||
751 | u32 clk_lane_switch_cnt; | 803 | u32 clk_lane_switch_cnt; |
804 | u32 hl_switch_cnt; | ||
805 | |||
806 | u32 rsvd11[6]; | ||
807 | |||
808 | /* timings based on dphy spec */ | ||
809 | u8 tclk_miss; | ||
810 | u8 tclk_post; | ||
811 | u8 rsvd12; | ||
812 | u8 tclk_pre; | ||
813 | u8 tclk_prepare; | ||
814 | u8 tclk_settle; | ||
815 | u8 tclk_term_enable; | ||
816 | u8 tclk_trail; | ||
817 | u16 tclk_prepare_clkzero; | ||
818 | u8 rsvd13; | ||
819 | u8 td_term_enable; | ||
820 | u8 teot; | ||
821 | u8 ths_exit; | ||
822 | u8 ths_prepare; | ||
823 | u16 ths_prepare_hszero; | ||
824 | u8 rsvd14; | ||
825 | u8 ths_settle; | ||
826 | u8 ths_skip; | ||
827 | u8 ths_trail; | ||
828 | u8 tinit; | ||
829 | u8 tlpx; | ||
830 | u8 rsvd15[3]; | ||
831 | |||
832 | /* GPIOs */ | ||
833 | u8 panel_enable; | ||
834 | u8 bl_enable; | ||
835 | u8 pwm_enable; | ||
836 | u8 reset_r_n; | ||
837 | u8 pwr_down_r; | ||
838 | u8 stdby_r_n; | ||
839 | |||
752 | } __packed; | 840 | } __packed; |
753 | 841 | ||
842 | /* Block 52 contains MIPI configuration block | ||
843 | * 6 * bdb_mipi_config, followed by 6 pps data | ||
844 | * block below | ||
845 | * | ||
846 | * all delays has a unit of 100us | ||
847 | */ | ||
848 | struct mipi_pps_data { | ||
849 | u16 panel_on_delay; | ||
850 | u16 bl_enable_delay; | ||
851 | u16 bl_disable_delay; | ||
852 | u16 panel_off_delay; | ||
853 | u16 panel_power_cycle_delay; | ||
854 | }; | ||
855 | |||
856 | struct bdb_mipi_config { | ||
857 | struct mipi_config config[MAX_MIPI_CONFIGURATIONS]; | ||
858 | struct mipi_pps_data pps[MAX_MIPI_CONFIGURATIONS]; | ||
859 | }; | ||
860 | |||
861 | /* Block 53 contains MIPI sequences as needed by the panel | ||
862 | * for enabling it. This block can be variable in size and | ||
863 | * can be maximum of 6 blocks | ||
864 | */ | ||
865 | struct bdb_mipi_sequence { | ||
866 | u8 version; | ||
867 | u8 data[0]; | ||
868 | }; | ||
869 | |||
754 | #endif /* _I830_BIOS_H_ */ | 870 | #endif /* _I830_BIOS_H_ */ |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 9864aa1ccbe8..4ef6d69c078d 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -68,8 +68,13 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder, | |||
68 | struct drm_device *dev = encoder->base.dev; | 68 | struct drm_device *dev = encoder->base.dev; |
69 | struct drm_i915_private *dev_priv = dev->dev_private; | 69 | struct drm_i915_private *dev_priv = dev->dev_private; |
70 | struct intel_crt *crt = intel_encoder_to_crt(encoder); | 70 | struct intel_crt *crt = intel_encoder_to_crt(encoder); |
71 | enum intel_display_power_domain power_domain; | ||
71 | u32 tmp; | 72 | u32 tmp; |
72 | 73 | ||
74 | power_domain = intel_display_port_power_domain(encoder); | ||
75 | if (!intel_display_power_enabled(dev_priv, power_domain)) | ||
76 | return false; | ||
77 | |||
73 | tmp = I915_READ(crt->adpa_reg); | 78 | tmp = I915_READ(crt->adpa_reg); |
74 | 79 | ||
75 | if (!(tmp & ADPA_DAC_ENABLE)) | 80 | if (!(tmp & ADPA_DAC_ENABLE)) |
@@ -262,6 +267,10 @@ static bool intel_crt_compute_config(struct intel_encoder *encoder, | |||
262 | if (HAS_PCH_LPT(dev)) | 267 | if (HAS_PCH_LPT(dev)) |
263 | pipe_config->pipe_bpp = 24; | 268 | pipe_config->pipe_bpp = 24; |
264 | 269 | ||
270 | /* FDI must always be 2.7 GHz */ | ||
271 | if (HAS_DDI(dev)) | ||
272 | pipe_config->port_clock = 135000 * 2; | ||
273 | |||
265 | return true; | 274 | return true; |
266 | } | 275 | } |
267 | 276 | ||
@@ -630,14 +639,22 @@ static enum drm_connector_status | |||
630 | intel_crt_detect(struct drm_connector *connector, bool force) | 639 | intel_crt_detect(struct drm_connector *connector, bool force) |
631 | { | 640 | { |
632 | struct drm_device *dev = connector->dev; | 641 | struct drm_device *dev = connector->dev; |
642 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
633 | struct intel_crt *crt = intel_attached_crt(connector); | 643 | struct intel_crt *crt = intel_attached_crt(connector); |
644 | struct intel_encoder *intel_encoder = &crt->base; | ||
645 | enum intel_display_power_domain power_domain; | ||
634 | enum drm_connector_status status; | 646 | enum drm_connector_status status; |
635 | struct intel_load_detect_pipe tmp; | 647 | struct intel_load_detect_pipe tmp; |
636 | 648 | ||
649 | intel_runtime_pm_get(dev_priv); | ||
650 | |||
637 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n", | 651 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n", |
638 | connector->base.id, drm_get_connector_name(connector), | 652 | connector->base.id, drm_get_connector_name(connector), |
639 | force); | 653 | force); |
640 | 654 | ||
655 | power_domain = intel_display_port_power_domain(intel_encoder); | ||
656 | intel_display_power_get(dev_priv, power_domain); | ||
657 | |||
641 | if (I915_HAS_HOTPLUG(dev)) { | 658 | if (I915_HAS_HOTPLUG(dev)) { |
642 | /* We can not rely on the HPD pin always being correctly wired | 659 | /* We can not rely on the HPD pin always being correctly wired |
643 | * up, for example many KVM do not pass it through, and so | 660 | * up, for example many KVM do not pass it through, and so |
@@ -645,23 +662,30 @@ intel_crt_detect(struct drm_connector *connector, bool force) | |||
645 | */ | 662 | */ |
646 | if (intel_crt_detect_hotplug(connector)) { | 663 | if (intel_crt_detect_hotplug(connector)) { |
647 | DRM_DEBUG_KMS("CRT detected via hotplug\n"); | 664 | DRM_DEBUG_KMS("CRT detected via hotplug\n"); |
648 | return connector_status_connected; | 665 | status = connector_status_connected; |
666 | goto out; | ||
649 | } else | 667 | } else |
650 | DRM_DEBUG_KMS("CRT not detected via hotplug\n"); | 668 | DRM_DEBUG_KMS("CRT not detected via hotplug\n"); |
651 | } | 669 | } |
652 | 670 | ||
653 | if (intel_crt_detect_ddc(connector)) | 671 | if (intel_crt_detect_ddc(connector)) { |
654 | return connector_status_connected; | 672 | status = connector_status_connected; |
673 | goto out; | ||
674 | } | ||
655 | 675 | ||
656 | /* Load detection is broken on HPD capable machines. Whoever wants a | 676 | /* Load detection is broken on HPD capable machines. Whoever wants a |
657 | * broken monitor (without edid) to work behind a broken kvm (that fails | 677 | * broken monitor (without edid) to work behind a broken kvm (that fails |
658 | * to have the right resistors for HP detection) needs to fix this up. | 678 | * to have the right resistors for HP detection) needs to fix this up. |
659 | * For now just bail out. */ | 679 | * For now just bail out. */ |
660 | if (I915_HAS_HOTPLUG(dev)) | 680 | if (I915_HAS_HOTPLUG(dev)) { |
661 | return connector_status_disconnected; | 681 | status = connector_status_disconnected; |
682 | goto out; | ||
683 | } | ||
662 | 684 | ||
663 | if (!force) | 685 | if (!force) { |
664 | return connector->status; | 686 | status = connector->status; |
687 | goto out; | ||
688 | } | ||
665 | 689 | ||
666 | /* for pre-945g platforms use load detect */ | 690 | /* for pre-945g platforms use load detect */ |
667 | if (intel_get_load_detect_pipe(connector, NULL, &tmp)) { | 691 | if (intel_get_load_detect_pipe(connector, NULL, &tmp)) { |
@@ -673,6 +697,10 @@ intel_crt_detect(struct drm_connector *connector, bool force) | |||
673 | } else | 697 | } else |
674 | status = connector_status_unknown; | 698 | status = connector_status_unknown; |
675 | 699 | ||
700 | out: | ||
701 | intel_display_power_put(dev_priv, power_domain); | ||
702 | intel_runtime_pm_put(dev_priv); | ||
703 | |||
676 | return status; | 704 | return status; |
677 | } | 705 | } |
678 | 706 | ||
@@ -686,17 +714,28 @@ static int intel_crt_get_modes(struct drm_connector *connector) | |||
686 | { | 714 | { |
687 | struct drm_device *dev = connector->dev; | 715 | struct drm_device *dev = connector->dev; |
688 | struct drm_i915_private *dev_priv = dev->dev_private; | 716 | struct drm_i915_private *dev_priv = dev->dev_private; |
717 | struct intel_crt *crt = intel_attached_crt(connector); | ||
718 | struct intel_encoder *intel_encoder = &crt->base; | ||
719 | enum intel_display_power_domain power_domain; | ||
689 | int ret; | 720 | int ret; |
690 | struct i2c_adapter *i2c; | 721 | struct i2c_adapter *i2c; |
691 | 722 | ||
723 | power_domain = intel_display_port_power_domain(intel_encoder); | ||
724 | intel_display_power_get(dev_priv, power_domain); | ||
725 | |||
692 | i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->vbt.crt_ddc_pin); | 726 | i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->vbt.crt_ddc_pin); |
693 | ret = intel_crt_ddc_get_modes(connector, i2c); | 727 | ret = intel_crt_ddc_get_modes(connector, i2c); |
694 | if (ret || !IS_G4X(dev)) | 728 | if (ret || !IS_G4X(dev)) |
695 | return ret; | 729 | goto out; |
696 | 730 | ||
697 | /* Try to probe digital port for output in DVI-I -> VGA mode. */ | 731 | /* Try to probe digital port for output in DVI-I -> VGA mode. */ |
698 | i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB); | 732 | i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB); |
699 | return intel_crt_ddc_get_modes(connector, i2c); | 733 | ret = intel_crt_ddc_get_modes(connector, i2c); |
734 | |||
735 | out: | ||
736 | intel_display_power_put(dev_priv, power_domain); | ||
737 | |||
738 | return ret; | ||
700 | } | 739 | } |
701 | 740 | ||
702 | static int intel_crt_set_property(struct drm_connector *connector, | 741 | static int intel_crt_set_property(struct drm_connector *connector, |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 2643d3b8b67d..e2665e09d5df 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -1145,9 +1145,14 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder, | |||
1145 | struct drm_device *dev = encoder->base.dev; | 1145 | struct drm_device *dev = encoder->base.dev; |
1146 | struct drm_i915_private *dev_priv = dev->dev_private; | 1146 | struct drm_i915_private *dev_priv = dev->dev_private; |
1147 | enum port port = intel_ddi_get_encoder_port(encoder); | 1147 | enum port port = intel_ddi_get_encoder_port(encoder); |
1148 | enum intel_display_power_domain power_domain; | ||
1148 | u32 tmp; | 1149 | u32 tmp; |
1149 | int i; | 1150 | int i; |
1150 | 1151 | ||
1152 | power_domain = intel_display_port_power_domain(encoder); | ||
1153 | if (!intel_display_power_enabled(dev_priv, power_domain)) | ||
1154 | return false; | ||
1155 | |||
1151 | tmp = I915_READ(DDI_BUF_CTL(port)); | 1156 | tmp = I915_READ(DDI_BUF_CTL(port)); |
1152 | 1157 | ||
1153 | if (!(tmp & DDI_BUF_CTL_ENABLE)) | 1158 | if (!(tmp & DDI_BUF_CTL_ENABLE)) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f19e6ea36dc4..11746e28243a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1122,7 +1122,7 @@ void assert_pipe(struct drm_i915_private *dev_priv, | |||
1122 | if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) | 1122 | if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) |
1123 | state = true; | 1123 | state = true; |
1124 | 1124 | ||
1125 | if (!intel_display_power_enabled(dev_priv->dev, | 1125 | if (!intel_display_power_enabled(dev_priv, |
1126 | POWER_DOMAIN_TRANSCODER(cpu_transcoder))) { | 1126 | POWER_DOMAIN_TRANSCODER(cpu_transcoder))) { |
1127 | cur_state = false; | 1127 | cur_state = false; |
1128 | } else { | 1128 | } else { |
@@ -1188,16 +1188,16 @@ static void assert_sprites_disabled(struct drm_i915_private *dev_priv, | |||
1188 | enum pipe pipe) | 1188 | enum pipe pipe) |
1189 | { | 1189 | { |
1190 | struct drm_device *dev = dev_priv->dev; | 1190 | struct drm_device *dev = dev_priv->dev; |
1191 | int reg, i; | 1191 | int reg, sprite; |
1192 | u32 val; | 1192 | u32 val; |
1193 | 1193 | ||
1194 | if (IS_VALLEYVIEW(dev)) { | 1194 | if (IS_VALLEYVIEW(dev)) { |
1195 | for (i = 0; i < INTEL_INFO(dev)->num_sprites; i++) { | 1195 | for_each_sprite(pipe, sprite) { |
1196 | reg = SPCNTR(pipe, i); | 1196 | reg = SPCNTR(pipe, sprite); |
1197 | val = I915_READ(reg); | 1197 | val = I915_READ(reg); |
1198 | WARN((val & SP_ENABLE), | 1198 | WARN((val & SP_ENABLE), |
1199 | "sprite %c assertion failure, should be off on pipe %c but is still active\n", | 1199 | "sprite %c assertion failure, should be off on pipe %c but is still active\n", |
1200 | sprite_name(pipe, i), pipe_name(pipe)); | 1200 | sprite_name(pipe, sprite), pipe_name(pipe)); |
1201 | } | 1201 | } |
1202 | } else if (INTEL_INFO(dev)->gen >= 7) { | 1202 | } else if (INTEL_INFO(dev)->gen >= 7) { |
1203 | reg = SPRCTL(pipe); | 1203 | reg = SPRCTL(pipe); |
@@ -2321,6 +2321,25 @@ intel_finish_fb(struct drm_framebuffer *old_fb) | |||
2321 | return ret; | 2321 | return ret; |
2322 | } | 2322 | } |
2323 | 2323 | ||
2324 | static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc) | ||
2325 | { | ||
2326 | struct drm_device *dev = crtc->dev; | ||
2327 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2328 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
2329 | unsigned long flags; | ||
2330 | bool pending; | ||
2331 | |||
2332 | if (i915_reset_in_progress(&dev_priv->gpu_error) || | ||
2333 | intel_crtc->reset_counter != atomic_read(&dev_priv->gpu_error.reset_counter)) | ||
2334 | return false; | ||
2335 | |||
2336 | spin_lock_irqsave(&dev->event_lock, flags); | ||
2337 | pending = to_intel_crtc(crtc)->unpin_work != NULL; | ||
2338 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
2339 | |||
2340 | return pending; | ||
2341 | } | ||
2342 | |||
2324 | static int | 2343 | static int |
2325 | intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | 2344 | intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, |
2326 | struct drm_framebuffer *fb) | 2345 | struct drm_framebuffer *fb) |
@@ -2331,6 +2350,11 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
2331 | struct drm_framebuffer *old_fb; | 2350 | struct drm_framebuffer *old_fb; |
2332 | int ret; | 2351 | int ret; |
2333 | 2352 | ||
2353 | if (intel_crtc_has_pending_flip(crtc)) { | ||
2354 | DRM_ERROR("pipe is still busy with an old pageflip\n"); | ||
2355 | return -EBUSY; | ||
2356 | } | ||
2357 | |||
2334 | /* no fb bound */ | 2358 | /* no fb bound */ |
2335 | if (!fb) { | 2359 | if (!fb) { |
2336 | DRM_ERROR("No FB bound\n"); | 2360 | DRM_ERROR("No FB bound\n"); |
@@ -2956,25 +2980,6 @@ static void ironlake_fdi_disable(struct drm_crtc *crtc) | |||
2956 | udelay(100); | 2980 | udelay(100); |
2957 | } | 2981 | } |
2958 | 2982 | ||
2959 | static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc) | ||
2960 | { | ||
2961 | struct drm_device *dev = crtc->dev; | ||
2962 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2963 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
2964 | unsigned long flags; | ||
2965 | bool pending; | ||
2966 | |||
2967 | if (i915_reset_in_progress(&dev_priv->gpu_error) || | ||
2968 | intel_crtc->reset_counter != atomic_read(&dev_priv->gpu_error.reset_counter)) | ||
2969 | return false; | ||
2970 | |||
2971 | spin_lock_irqsave(&dev->event_lock, flags); | ||
2972 | pending = to_intel_crtc(crtc)->unpin_work != NULL; | ||
2973 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
2974 | |||
2975 | return pending; | ||
2976 | } | ||
2977 | |||
2978 | bool intel_has_pending_fb_unpin(struct drm_device *dev) | 2983 | bool intel_has_pending_fb_unpin(struct drm_device *dev) |
2979 | { | 2984 | { |
2980 | struct intel_crtc *crtc; | 2985 | struct intel_crtc *crtc; |
@@ -3953,6 +3958,117 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc) | |||
3953 | I915_WRITE(BCLRPAT(crtc->pipe), 0); | 3958 | I915_WRITE(BCLRPAT(crtc->pipe), 0); |
3954 | } | 3959 | } |
3955 | 3960 | ||
3961 | #define for_each_power_domain(domain, mask) \ | ||
3962 | for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \ | ||
3963 | if ((1 << (domain)) & (mask)) | ||
3964 | |||
3965 | enum intel_display_power_domain | ||
3966 | intel_display_port_power_domain(struct intel_encoder *intel_encoder) | ||
3967 | { | ||
3968 | struct drm_device *dev = intel_encoder->base.dev; | ||
3969 | struct intel_digital_port *intel_dig_port; | ||
3970 | |||
3971 | switch (intel_encoder->type) { | ||
3972 | case INTEL_OUTPUT_UNKNOWN: | ||
3973 | /* Only DDI platforms should ever use this output type */ | ||
3974 | WARN_ON_ONCE(!HAS_DDI(dev)); | ||
3975 | case INTEL_OUTPUT_DISPLAYPORT: | ||
3976 | case INTEL_OUTPUT_HDMI: | ||
3977 | case INTEL_OUTPUT_EDP: | ||
3978 | intel_dig_port = enc_to_dig_port(&intel_encoder->base); | ||
3979 | switch (intel_dig_port->port) { | ||
3980 | case PORT_A: | ||
3981 | return POWER_DOMAIN_PORT_DDI_A_4_LANES; | ||
3982 | case PORT_B: | ||
3983 | return POWER_DOMAIN_PORT_DDI_B_4_LANES; | ||
3984 | case PORT_C: | ||
3985 | return POWER_DOMAIN_PORT_DDI_C_4_LANES; | ||
3986 | case PORT_D: | ||
3987 | return POWER_DOMAIN_PORT_DDI_D_4_LANES; | ||
3988 | default: | ||
3989 | WARN_ON_ONCE(1); | ||
3990 | return POWER_DOMAIN_PORT_OTHER; | ||
3991 | } | ||
3992 | case INTEL_OUTPUT_ANALOG: | ||
3993 | return POWER_DOMAIN_PORT_CRT; | ||
3994 | case INTEL_OUTPUT_DSI: | ||
3995 | return POWER_DOMAIN_PORT_DSI; | ||
3996 | default: | ||
3997 | return POWER_DOMAIN_PORT_OTHER; | ||
3998 | } | ||
3999 | } | ||
4000 | |||
4001 | static unsigned long get_crtc_power_domains(struct drm_crtc *crtc) | ||
4002 | { | ||
4003 | struct drm_device *dev = crtc->dev; | ||
4004 | struct intel_encoder *intel_encoder; | ||
4005 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
4006 | enum pipe pipe = intel_crtc->pipe; | ||
4007 | bool pfit_enabled = intel_crtc->config.pch_pfit.enabled; | ||
4008 | unsigned long mask; | ||
4009 | enum transcoder transcoder; | ||
4010 | |||
4011 | transcoder = intel_pipe_to_cpu_transcoder(dev->dev_private, pipe); | ||
4012 | |||
4013 | mask = BIT(POWER_DOMAIN_PIPE(pipe)); | ||
4014 | mask |= BIT(POWER_DOMAIN_TRANSCODER(transcoder)); | ||
4015 | if (pfit_enabled) | ||
4016 | mask |= BIT(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe)); | ||
4017 | |||
4018 | for_each_encoder_on_crtc(dev, crtc, intel_encoder) | ||
4019 | mask |= BIT(intel_display_port_power_domain(intel_encoder)); | ||
4020 | |||
4021 | return mask; | ||
4022 | } | ||
4023 | |||
4024 | void intel_display_set_init_power(struct drm_i915_private *dev_priv, | ||
4025 | bool enable) | ||
4026 | { | ||
4027 | if (dev_priv->power_domains.init_power_on == enable) | ||
4028 | return; | ||
4029 | |||
4030 | if (enable) | ||
4031 | intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); | ||
4032 | else | ||
4033 | intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); | ||
4034 | |||
4035 | dev_priv->power_domains.init_power_on = enable; | ||
4036 | } | ||
4037 | |||
4038 | static void modeset_update_crtc_power_domains(struct drm_device *dev) | ||
4039 | { | ||
4040 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4041 | unsigned long pipe_domains[I915_MAX_PIPES] = { 0, }; | ||
4042 | struct intel_crtc *crtc; | ||
4043 | |||
4044 | /* | ||
4045 | * First get all needed power domains, then put all unneeded, to avoid | ||
4046 | * any unnecessary toggling of the power wells. | ||
4047 | */ | ||
4048 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) { | ||
4049 | enum intel_display_power_domain domain; | ||
4050 | |||
4051 | if (!crtc->base.enabled) | ||
4052 | continue; | ||
4053 | |||
4054 | pipe_domains[crtc->pipe] = get_crtc_power_domains(&crtc->base); | ||
4055 | |||
4056 | for_each_power_domain(domain, pipe_domains[crtc->pipe]) | ||
4057 | intel_display_power_get(dev_priv, domain); | ||
4058 | } | ||
4059 | |||
4060 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) { | ||
4061 | enum intel_display_power_domain domain; | ||
4062 | |||
4063 | for_each_power_domain(domain, crtc->enabled_power_domains) | ||
4064 | intel_display_power_put(dev_priv, domain); | ||
4065 | |||
4066 | crtc->enabled_power_domains = pipe_domains[crtc->pipe]; | ||
4067 | } | ||
4068 | |||
4069 | intel_display_set_init_power(dev_priv, false); | ||
4070 | } | ||
4071 | |||
3956 | int valleyview_get_vco(struct drm_i915_private *dev_priv) | 4072 | int valleyview_get_vco(struct drm_i915_private *dev_priv) |
3957 | { | 4073 | { |
3958 | int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 }; | 4074 | int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 }; |
@@ -4113,6 +4229,7 @@ static void valleyview_modeset_global_resources(struct drm_device *dev) | |||
4113 | 4229 | ||
4114 | if (req_cdclk != cur_cdclk) | 4230 | if (req_cdclk != cur_cdclk) |
4115 | valleyview_set_cdclk(dev, req_cdclk); | 4231 | valleyview_set_cdclk(dev, req_cdclk); |
4232 | modeset_update_crtc_power_domains(dev); | ||
4116 | } | 4233 | } |
4117 | 4234 | ||
4118 | static void valleyview_crtc_enable(struct drm_crtc *crtc) | 4235 | static void valleyview_crtc_enable(struct drm_crtc *crtc) |
@@ -5495,6 +5612,10 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, | |||
5495 | struct drm_i915_private *dev_priv = dev->dev_private; | 5612 | struct drm_i915_private *dev_priv = dev->dev_private; |
5496 | uint32_t tmp; | 5613 | uint32_t tmp; |
5497 | 5614 | ||
5615 | if (!intel_display_power_enabled(dev_priv, | ||
5616 | POWER_DOMAIN_PIPE(crtc->pipe))) | ||
5617 | return false; | ||
5618 | |||
5498 | pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; | 5619 | pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; |
5499 | pipe_config->shared_dpll = DPLL_ID_PRIVATE; | 5620 | pipe_config->shared_dpll = DPLL_ID_PRIVATE; |
5500 | 5621 | ||
@@ -6156,7 +6277,7 @@ int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp) | |||
6156 | * is 2.5%; use 5% for safety's sake. | 6277 | * is 2.5%; use 5% for safety's sake. |
6157 | */ | 6278 | */ |
6158 | u32 bps = target_clock * bpp * 21 / 20; | 6279 | u32 bps = target_clock * bpp * 21 / 20; |
6159 | return bps / (link_bw * 8) + 1; | 6280 | return DIV_ROUND_UP(bps, link_bw * 8); |
6160 | } | 6281 | } |
6161 | 6282 | ||
6162 | static bool ironlake_needs_fb_cb_tune(struct dpll *dpll, int factor) | 6283 | static bool ironlake_needs_fb_cb_tune(struct dpll *dpll, int factor) |
@@ -6812,105 +6933,9 @@ done: | |||
6812 | mutex_unlock(&dev_priv->pc8.lock); | 6933 | mutex_unlock(&dev_priv->pc8.lock); |
6813 | } | 6934 | } |
6814 | 6935 | ||
6815 | static void hsw_package_c8_gpu_idle(struct drm_i915_private *dev_priv) | ||
6816 | { | ||
6817 | if (!HAS_PC8(dev_priv->dev)) | ||
6818 | return; | ||
6819 | |||
6820 | mutex_lock(&dev_priv->pc8.lock); | ||
6821 | if (!dev_priv->pc8.gpu_idle) { | ||
6822 | dev_priv->pc8.gpu_idle = true; | ||
6823 | __hsw_enable_package_c8(dev_priv); | ||
6824 | } | ||
6825 | mutex_unlock(&dev_priv->pc8.lock); | ||
6826 | } | ||
6827 | |||
6828 | static void hsw_package_c8_gpu_busy(struct drm_i915_private *dev_priv) | ||
6829 | { | ||
6830 | if (!HAS_PC8(dev_priv->dev)) | ||
6831 | return; | ||
6832 | |||
6833 | mutex_lock(&dev_priv->pc8.lock); | ||
6834 | if (dev_priv->pc8.gpu_idle) { | ||
6835 | dev_priv->pc8.gpu_idle = false; | ||
6836 | __hsw_disable_package_c8(dev_priv); | ||
6837 | } | ||
6838 | mutex_unlock(&dev_priv->pc8.lock); | ||
6839 | } | ||
6840 | |||
6841 | #define for_each_power_domain(domain, mask) \ | ||
6842 | for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \ | ||
6843 | if ((1 << (domain)) & (mask)) | ||
6844 | |||
6845 | static unsigned long get_pipe_power_domains(struct drm_device *dev, | ||
6846 | enum pipe pipe, bool pfit_enabled) | ||
6847 | { | ||
6848 | unsigned long mask; | ||
6849 | enum transcoder transcoder; | ||
6850 | |||
6851 | transcoder = intel_pipe_to_cpu_transcoder(dev->dev_private, pipe); | ||
6852 | |||
6853 | mask = BIT(POWER_DOMAIN_PIPE(pipe)); | ||
6854 | mask |= BIT(POWER_DOMAIN_TRANSCODER(transcoder)); | ||
6855 | if (pfit_enabled) | ||
6856 | mask |= BIT(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe)); | ||
6857 | |||
6858 | return mask; | ||
6859 | } | ||
6860 | |||
6861 | void intel_display_set_init_power(struct drm_device *dev, bool enable) | ||
6862 | { | ||
6863 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
6864 | |||
6865 | if (dev_priv->power_domains.init_power_on == enable) | ||
6866 | return; | ||
6867 | |||
6868 | if (enable) | ||
6869 | intel_display_power_get(dev, POWER_DOMAIN_INIT); | ||
6870 | else | ||
6871 | intel_display_power_put(dev, POWER_DOMAIN_INIT); | ||
6872 | |||
6873 | dev_priv->power_domains.init_power_on = enable; | ||
6874 | } | ||
6875 | |||
6876 | static void modeset_update_power_wells(struct drm_device *dev) | ||
6877 | { | ||
6878 | unsigned long pipe_domains[I915_MAX_PIPES] = { 0, }; | ||
6879 | struct intel_crtc *crtc; | ||
6880 | |||
6881 | /* | ||
6882 | * First get all needed power domains, then put all unneeded, to avoid | ||
6883 | * any unnecessary toggling of the power wells. | ||
6884 | */ | ||
6885 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) { | ||
6886 | enum intel_display_power_domain domain; | ||
6887 | |||
6888 | if (!crtc->base.enabled) | ||
6889 | continue; | ||
6890 | |||
6891 | pipe_domains[crtc->pipe] = get_pipe_power_domains(dev, | ||
6892 | crtc->pipe, | ||
6893 | crtc->config.pch_pfit.enabled); | ||
6894 | |||
6895 | for_each_power_domain(domain, pipe_domains[crtc->pipe]) | ||
6896 | intel_display_power_get(dev, domain); | ||
6897 | } | ||
6898 | |||
6899 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) { | ||
6900 | enum intel_display_power_domain domain; | ||
6901 | |||
6902 | for_each_power_domain(domain, crtc->enabled_power_domains) | ||
6903 | intel_display_power_put(dev, domain); | ||
6904 | |||
6905 | crtc->enabled_power_domains = pipe_domains[crtc->pipe]; | ||
6906 | } | ||
6907 | |||
6908 | intel_display_set_init_power(dev, false); | ||
6909 | } | ||
6910 | |||
6911 | static void haswell_modeset_global_resources(struct drm_device *dev) | 6936 | static void haswell_modeset_global_resources(struct drm_device *dev) |
6912 | { | 6937 | { |
6913 | modeset_update_power_wells(dev); | 6938 | modeset_update_crtc_power_domains(dev); |
6914 | hsw_update_package_c8(dev); | 6939 | hsw_update_package_c8(dev); |
6915 | } | 6940 | } |
6916 | 6941 | ||
@@ -6961,6 +6986,10 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, | |||
6961 | enum intel_display_power_domain pfit_domain; | 6986 | enum intel_display_power_domain pfit_domain; |
6962 | uint32_t tmp; | 6987 | uint32_t tmp; |
6963 | 6988 | ||
6989 | if (!intel_display_power_enabled(dev_priv, | ||
6990 | POWER_DOMAIN_PIPE(crtc->pipe))) | ||
6991 | return false; | ||
6992 | |||
6964 | pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; | 6993 | pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; |
6965 | pipe_config->shared_dpll = DPLL_ID_PRIVATE; | 6994 | pipe_config->shared_dpll = DPLL_ID_PRIVATE; |
6966 | 6995 | ||
@@ -6986,7 +7015,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, | |||
6986 | pipe_config->cpu_transcoder = TRANSCODER_EDP; | 7015 | pipe_config->cpu_transcoder = TRANSCODER_EDP; |
6987 | } | 7016 | } |
6988 | 7017 | ||
6989 | if (!intel_display_power_enabled(dev, | 7018 | if (!intel_display_power_enabled(dev_priv, |
6990 | POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder))) | 7019 | POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder))) |
6991 | return false; | 7020 | return false; |
6992 | 7021 | ||
@@ -7014,7 +7043,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, | |||
7014 | intel_get_pipe_timings(crtc, pipe_config); | 7043 | intel_get_pipe_timings(crtc, pipe_config); |
7015 | 7044 | ||
7016 | pfit_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe); | 7045 | pfit_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe); |
7017 | if (intel_display_power_enabled(dev, pfit_domain)) | 7046 | if (intel_display_power_enabled(dev_priv, pfit_domain)) |
7018 | ironlake_get_pfit_config(crtc, pipe_config); | 7047 | ironlake_get_pfit_config(crtc, pipe_config); |
7019 | 7048 | ||
7020 | if (IS_HASWELL(dev)) | 7049 | if (IS_HASWELL(dev)) |
@@ -7549,7 +7578,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
7549 | return -ENOENT; | 7578 | return -ENOENT; |
7550 | 7579 | ||
7551 | if (obj->base.size < width * height * 4) { | 7580 | if (obj->base.size < width * height * 4) { |
7552 | DRM_ERROR("buffer is to small\n"); | 7581 | DRM_DEBUG_KMS("buffer is to small\n"); |
7553 | ret = -ENOMEM; | 7582 | ret = -ENOMEM; |
7554 | goto fail; | 7583 | goto fail; |
7555 | } | 7584 | } |
@@ -7560,7 +7589,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
7560 | unsigned alignment; | 7589 | unsigned alignment; |
7561 | 7590 | ||
7562 | if (obj->tiling_mode) { | 7591 | if (obj->tiling_mode) { |
7563 | DRM_ERROR("cursor cannot be tiled\n"); | 7592 | DRM_DEBUG_KMS("cursor cannot be tiled\n"); |
7564 | ret = -EINVAL; | 7593 | ret = -EINVAL; |
7565 | goto fail_locked; | 7594 | goto fail_locked; |
7566 | } | 7595 | } |
@@ -7576,13 +7605,13 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
7576 | 7605 | ||
7577 | ret = i915_gem_object_pin_to_display_plane(obj, alignment, NULL); | 7606 | ret = i915_gem_object_pin_to_display_plane(obj, alignment, NULL); |
7578 | if (ret) { | 7607 | if (ret) { |
7579 | DRM_ERROR("failed to move cursor bo into the GTT\n"); | 7608 | DRM_DEBUG_KMS("failed to move cursor bo into the GTT\n"); |
7580 | goto fail_locked; | 7609 | goto fail_locked; |
7581 | } | 7610 | } |
7582 | 7611 | ||
7583 | ret = i915_gem_object_put_fence(obj); | 7612 | ret = i915_gem_object_put_fence(obj); |
7584 | if (ret) { | 7613 | if (ret) { |
7585 | DRM_ERROR("failed to release fence for cursor"); | 7614 | DRM_DEBUG_KMS("failed to release fence for cursor"); |
7586 | goto fail_unpin; | 7615 | goto fail_unpin; |
7587 | } | 7616 | } |
7588 | 7617 | ||
@@ -7593,7 +7622,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
7593 | (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1, | 7622 | (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1, |
7594 | align); | 7623 | align); |
7595 | if (ret) { | 7624 | if (ret) { |
7596 | DRM_ERROR("failed to attach phys object\n"); | 7625 | DRM_DEBUG_KMS("failed to attach phys object\n"); |
7597 | goto fail_locked; | 7626 | goto fail_locked; |
7598 | } | 7627 | } |
7599 | addr = obj->phys_obj->handle->busaddr; | 7628 | addr = obj->phys_obj->handle->busaddr; |
@@ -7692,7 +7721,7 @@ err: | |||
7692 | return ERR_PTR(ret); | 7721 | return ERR_PTR(ret); |
7693 | } | 7722 | } |
7694 | 7723 | ||
7695 | struct drm_framebuffer * | 7724 | static struct drm_framebuffer * |
7696 | intel_framebuffer_create(struct drm_device *dev, | 7725 | intel_framebuffer_create(struct drm_device *dev, |
7697 | struct drm_mode_fb_cmd2 *mode_cmd, | 7726 | struct drm_mode_fb_cmd2 *mode_cmd, |
7698 | struct drm_i915_gem_object *obj) | 7727 | struct drm_i915_gem_object *obj) |
@@ -8192,8 +8221,12 @@ void intel_mark_busy(struct drm_device *dev) | |||
8192 | { | 8221 | { |
8193 | struct drm_i915_private *dev_priv = dev->dev_private; | 8222 | struct drm_i915_private *dev_priv = dev->dev_private; |
8194 | 8223 | ||
8195 | hsw_package_c8_gpu_busy(dev_priv); | 8224 | if (dev_priv->mm.busy) |
8225 | return; | ||
8226 | |||
8227 | hsw_disable_package_c8(dev_priv); | ||
8196 | i915_update_gfx_val(dev_priv); | 8228 | i915_update_gfx_val(dev_priv); |
8229 | dev_priv->mm.busy = true; | ||
8197 | } | 8230 | } |
8198 | 8231 | ||
8199 | void intel_mark_idle(struct drm_device *dev) | 8232 | void intel_mark_idle(struct drm_device *dev) |
@@ -8201,10 +8234,13 @@ void intel_mark_idle(struct drm_device *dev) | |||
8201 | struct drm_i915_private *dev_priv = dev->dev_private; | 8234 | struct drm_i915_private *dev_priv = dev->dev_private; |
8202 | struct drm_crtc *crtc; | 8235 | struct drm_crtc *crtc; |
8203 | 8236 | ||
8204 | hsw_package_c8_gpu_idle(dev_priv); | 8237 | if (!dev_priv->mm.busy) |
8238 | return; | ||
8239 | |||
8240 | dev_priv->mm.busy = false; | ||
8205 | 8241 | ||
8206 | if (!i915.powersave) | 8242 | if (!i915.powersave) |
8207 | return; | 8243 | goto out; |
8208 | 8244 | ||
8209 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 8245 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
8210 | if (!crtc->fb) | 8246 | if (!crtc->fb) |
@@ -8215,6 +8251,9 @@ void intel_mark_idle(struct drm_device *dev) | |||
8215 | 8251 | ||
8216 | if (INTEL_INFO(dev)->gen >= 6) | 8252 | if (INTEL_INFO(dev)->gen >= 6) |
8217 | gen6_rps_idle(dev->dev_private); | 8253 | gen6_rps_idle(dev->dev_private); |
8254 | |||
8255 | out: | ||
8256 | hsw_enable_package_c8(dev_priv); | ||
8218 | } | 8257 | } |
8219 | 8258 | ||
8220 | void intel_mark_fb_busy(struct drm_i915_gem_object *obj, | 8259 | void intel_mark_fb_busy(struct drm_i915_gem_object *obj, |
@@ -8678,6 +8717,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
8678 | fb->pitches[0] != crtc->fb->pitches[0])) | 8717 | fb->pitches[0] != crtc->fb->pitches[0])) |
8679 | return -EINVAL; | 8718 | return -EINVAL; |
8680 | 8719 | ||
8720 | if (i915_terminally_wedged(&dev_priv->gpu_error)) | ||
8721 | goto out_hang; | ||
8722 | |||
8681 | work = kzalloc(sizeof(*work), GFP_KERNEL); | 8723 | work = kzalloc(sizeof(*work), GFP_KERNEL); |
8682 | if (work == NULL) | 8724 | if (work == NULL) |
8683 | return -ENOMEM; | 8725 | return -ENOMEM; |
@@ -8752,6 +8794,13 @@ cleanup: | |||
8752 | free_work: | 8794 | free_work: |
8753 | kfree(work); | 8795 | kfree(work); |
8754 | 8796 | ||
8797 | if (ret == -EIO) { | ||
8798 | out_hang: | ||
8799 | intel_crtc_wait_for_pending_flips(crtc); | ||
8800 | ret = intel_pipe_set_base(crtc, crtc->x, crtc->y, fb); | ||
8801 | if (ret == 0 && event) | ||
8802 | drm_send_vblank_event(dev, intel_crtc->pipe, event); | ||
8803 | } | ||
8755 | return ret; | 8804 | return ret; |
8756 | } | 8805 | } |
8757 | 8806 | ||
@@ -10555,10 +10604,10 @@ static const struct drm_framebuffer_funcs intel_fb_funcs = { | |||
10555 | .create_handle = intel_user_framebuffer_create_handle, | 10604 | .create_handle = intel_user_framebuffer_create_handle, |
10556 | }; | 10605 | }; |
10557 | 10606 | ||
10558 | int intel_framebuffer_init(struct drm_device *dev, | 10607 | static int intel_framebuffer_init(struct drm_device *dev, |
10559 | struct intel_framebuffer *intel_fb, | 10608 | struct intel_framebuffer *intel_fb, |
10560 | struct drm_mode_fb_cmd2 *mode_cmd, | 10609 | struct drm_mode_fb_cmd2 *mode_cmd, |
10561 | struct drm_i915_gem_object *obj) | 10610 | struct drm_i915_gem_object *obj) |
10562 | { | 10611 | { |
10563 | int aligned_height; | 10612 | int aligned_height; |
10564 | int pitch_limit; | 10613 | int pitch_limit; |
@@ -10996,7 +11045,8 @@ void intel_modeset_suspend_hw(struct drm_device *dev) | |||
10996 | void intel_modeset_init(struct drm_device *dev) | 11045 | void intel_modeset_init(struct drm_device *dev) |
10997 | { | 11046 | { |
10998 | struct drm_i915_private *dev_priv = dev->dev_private; | 11047 | struct drm_i915_private *dev_priv = dev->dev_private; |
10999 | int i, j, ret; | 11048 | int sprite, ret; |
11049 | enum pipe pipe; | ||
11000 | 11050 | ||
11001 | drm_mode_config_init(dev); | 11051 | drm_mode_config_init(dev); |
11002 | 11052 | ||
@@ -11033,13 +11083,13 @@ void intel_modeset_init(struct drm_device *dev) | |||
11033 | INTEL_INFO(dev)->num_pipes, | 11083 | INTEL_INFO(dev)->num_pipes, |
11034 | INTEL_INFO(dev)->num_pipes > 1 ? "s" : ""); | 11084 | INTEL_INFO(dev)->num_pipes > 1 ? "s" : ""); |
11035 | 11085 | ||
11036 | for_each_pipe(i) { | 11086 | for_each_pipe(pipe) { |
11037 | intel_crtc_init(dev, i); | 11087 | intel_crtc_init(dev, pipe); |
11038 | for (j = 0; j < INTEL_INFO(dev)->num_sprites; j++) { | 11088 | for_each_sprite(pipe, sprite) { |
11039 | ret = intel_plane_init(dev, i, j); | 11089 | ret = intel_plane_init(dev, pipe, sprite); |
11040 | if (ret) | 11090 | if (ret) |
11041 | DRM_DEBUG_KMS("pipe %c sprite %c init failed: %d\n", | 11091 | DRM_DEBUG_KMS("pipe %c sprite %c init failed: %d\n", |
11042 | pipe_name(i), sprite_name(i, j), ret); | 11092 | pipe_name(pipe), sprite_name(pipe, sprite), ret); |
11043 | } | 11093 | } |
11044 | } | 11094 | } |
11045 | 11095 | ||
@@ -11056,7 +11106,9 @@ void intel_modeset_init(struct drm_device *dev) | |||
11056 | /* Just in case the BIOS is doing something questionable. */ | 11106 | /* Just in case the BIOS is doing something questionable. */ |
11057 | intel_disable_fbc(dev); | 11107 | intel_disable_fbc(dev); |
11058 | 11108 | ||
11109 | mutex_lock(&dev->mode_config.mutex); | ||
11059 | intel_modeset_setup_hw_state(dev, false); | 11110 | intel_modeset_setup_hw_state(dev, false); |
11111 | mutex_unlock(&dev->mode_config.mutex); | ||
11060 | } | 11112 | } |
11061 | 11113 | ||
11062 | static void | 11114 | static void |
@@ -11239,11 +11291,21 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder) | |||
11239 | * the crtc fixup. */ | 11291 | * the crtc fixup. */ |
11240 | } | 11292 | } |
11241 | 11293 | ||
11242 | void i915_redisable_vga(struct drm_device *dev) | 11294 | void i915_redisable_vga_power_on(struct drm_device *dev) |
11243 | { | 11295 | { |
11244 | struct drm_i915_private *dev_priv = dev->dev_private; | 11296 | struct drm_i915_private *dev_priv = dev->dev_private; |
11245 | u32 vga_reg = i915_vgacntrl_reg(dev); | 11297 | u32 vga_reg = i915_vgacntrl_reg(dev); |
11246 | 11298 | ||
11299 | if (!(I915_READ(vga_reg) & VGA_DISP_DISABLE)) { | ||
11300 | DRM_DEBUG_KMS("Something enabled VGA plane, disabling it\n"); | ||
11301 | i915_disable_vga(dev); | ||
11302 | } | ||
11303 | } | ||
11304 | |||
11305 | void i915_redisable_vga(struct drm_device *dev) | ||
11306 | { | ||
11307 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
11308 | |||
11247 | /* This function can be called both from intel_modeset_setup_hw_state or | 11309 | /* This function can be called both from intel_modeset_setup_hw_state or |
11248 | * at a very early point in our resume sequence, where the power well | 11310 | * at a very early point in our resume sequence, where the power well |
11249 | * structures are not yet restored. Since this function is at a very | 11311 | * structures are not yet restored. Since this function is at a very |
@@ -11251,14 +11313,10 @@ void i915_redisable_vga(struct drm_device *dev) | |||
11251 | * level, just check if the power well is enabled instead of trying to | 11313 | * level, just check if the power well is enabled instead of trying to |
11252 | * follow the "don't touch the power well if we don't need it" policy | 11314 | * follow the "don't touch the power well if we don't need it" policy |
11253 | * the rest of the driver uses. */ | 11315 | * the rest of the driver uses. */ |
11254 | if ((IS_HASWELL(dev) || IS_BROADWELL(dev)) && | 11316 | if (!intel_display_power_enabled(dev_priv, POWER_DOMAIN_VGA)) |
11255 | (I915_READ(HSW_PWR_WELL_DRIVER) & HSW_PWR_WELL_STATE_ENABLED) == 0) | ||
11256 | return; | 11317 | return; |
11257 | 11318 | ||
11258 | if (!(I915_READ(vga_reg) & VGA_DISP_DISABLE)) { | 11319 | i915_redisable_vga_power_on(dev); |
11259 | DRM_DEBUG_KMS("Something enabled VGA plane, disabling it\n"); | ||
11260 | i915_disable_vga(dev); | ||
11261 | } | ||
11262 | } | 11320 | } |
11263 | 11321 | ||
11264 | static void intel_modeset_readout_hw_state(struct drm_device *dev) | 11322 | static void intel_modeset_readout_hw_state(struct drm_device *dev) |
@@ -11602,7 +11660,8 @@ intel_display_capture_error_state(struct drm_device *dev) | |||
11602 | 11660 | ||
11603 | for_each_pipe(i) { | 11661 | for_each_pipe(i) { |
11604 | error->pipe[i].power_domain_on = | 11662 | error->pipe[i].power_domain_on = |
11605 | intel_display_power_enabled_sw(dev, POWER_DOMAIN_PIPE(i)); | 11663 | intel_display_power_enabled_sw(dev_priv, |
11664 | POWER_DOMAIN_PIPE(i)); | ||
11606 | if (!error->pipe[i].power_domain_on) | 11665 | if (!error->pipe[i].power_domain_on) |
11607 | continue; | 11666 | continue; |
11608 | 11667 | ||
@@ -11640,7 +11699,7 @@ intel_display_capture_error_state(struct drm_device *dev) | |||
11640 | enum transcoder cpu_transcoder = transcoders[i]; | 11699 | enum transcoder cpu_transcoder = transcoders[i]; |
11641 | 11700 | ||
11642 | error->transcoder[i].power_domain_on = | 11701 | error->transcoder[i].power_domain_on = |
11643 | intel_display_power_enabled_sw(dev, | 11702 | intel_display_power_enabled_sw(dev_priv, |
11644 | POWER_DOMAIN_TRANSCODER(cpu_transcoder)); | 11703 | POWER_DOMAIN_TRANSCODER(cpu_transcoder)); |
11645 | if (!error->transcoder[i].power_domain_on) | 11704 | if (!error->transcoder[i].power_domain_on) |
11646 | continue; | 11705 | continue; |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c512d78af271..49d12d341ab2 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -916,8 +916,8 @@ intel_dp_compute_config(struct intel_encoder *encoder, | |||
916 | mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, | 916 | mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, |
917 | bpp); | 917 | bpp); |
918 | 918 | ||
919 | for (clock = 0; clock <= max_clock; clock++) { | 919 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { |
920 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { | 920 | for (clock = 0; clock <= max_clock; clock++) { |
921 | link_clock = drm_dp_bw_code_to_link_rate(bws[clock]); | 921 | link_clock = drm_dp_bw_code_to_link_rate(bws[clock]); |
922 | link_avail = intel_dp_max_data_rate(link_clock, | 922 | link_avail = intel_dp_max_data_rate(link_clock, |
923 | lane_count); | 923 | lane_count); |
@@ -1333,7 +1333,8 @@ void intel_edp_panel_off(struct intel_dp *intel_dp) | |||
1333 | pp = ironlake_get_pp_control(intel_dp); | 1333 | pp = ironlake_get_pp_control(intel_dp); |
1334 | /* We need to switch off panel power _and_ force vdd, for otherwise some | 1334 | /* We need to switch off panel power _and_ force vdd, for otherwise some |
1335 | * panels get very unhappy and cease to work. */ | 1335 | * panels get very unhappy and cease to work. */ |
1336 | pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_BLC_ENABLE); | 1336 | pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_FORCE_VDD | |
1337 | EDP_BLC_ENABLE); | ||
1337 | 1338 | ||
1338 | pp_ctrl_reg = _pp_ctrl_reg(intel_dp); | 1339 | pp_ctrl_reg = _pp_ctrl_reg(intel_dp); |
1339 | 1340 | ||
@@ -1485,7 +1486,14 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder, | |||
1485 | enum port port = dp_to_dig_port(intel_dp)->port; | 1486 | enum port port = dp_to_dig_port(intel_dp)->port; |
1486 | struct drm_device *dev = encoder->base.dev; | 1487 | struct drm_device *dev = encoder->base.dev; |
1487 | struct drm_i915_private *dev_priv = dev->dev_private; | 1488 | struct drm_i915_private *dev_priv = dev->dev_private; |
1488 | u32 tmp = I915_READ(intel_dp->output_reg); | 1489 | enum intel_display_power_domain power_domain; |
1490 | u32 tmp; | ||
1491 | |||
1492 | power_domain = intel_display_port_power_domain(encoder); | ||
1493 | if (!intel_display_power_enabled(dev_priv, power_domain)) | ||
1494 | return false; | ||
1495 | |||
1496 | tmp = I915_READ(intel_dp->output_reg); | ||
1489 | 1497 | ||
1490 | if (!(tmp & DP_PORT_EN)) | 1498 | if (!(tmp & DP_PORT_EN)) |
1491 | return false; | 1499 | return false; |
@@ -1868,9 +1876,11 @@ static void intel_disable_dp(struct intel_encoder *encoder) | |||
1868 | 1876 | ||
1869 | /* Make sure the panel is off before trying to change the mode. But also | 1877 | /* Make sure the panel is off before trying to change the mode. But also |
1870 | * ensure that we have vdd while we switch off the panel. */ | 1878 | * ensure that we have vdd while we switch off the panel. */ |
1879 | edp_panel_vdd_on(intel_dp); | ||
1871 | intel_edp_backlight_off(intel_dp); | 1880 | intel_edp_backlight_off(intel_dp); |
1872 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); | 1881 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); |
1873 | intel_edp_panel_off(intel_dp); | 1882 | intel_edp_panel_off(intel_dp); |
1883 | edp_panel_vdd_off(intel_dp, true); | ||
1874 | 1884 | ||
1875 | /* cpu edp my only be disable _after_ the cpu pipe/plane is disabled. */ | 1885 | /* cpu edp my only be disable _after_ the cpu pipe/plane is disabled. */ |
1876 | if (!(port == PORT_A || IS_VALLEYVIEW(dev))) | 1886 | if (!(port == PORT_A || IS_VALLEYVIEW(dev))) |
@@ -3224,10 +3234,14 @@ intel_dp_detect(struct drm_connector *connector, bool force) | |||
3224 | struct drm_device *dev = connector->dev; | 3234 | struct drm_device *dev = connector->dev; |
3225 | struct drm_i915_private *dev_priv = dev->dev_private; | 3235 | struct drm_i915_private *dev_priv = dev->dev_private; |
3226 | enum drm_connector_status status; | 3236 | enum drm_connector_status status; |
3237 | enum intel_display_power_domain power_domain; | ||
3227 | struct edid *edid = NULL; | 3238 | struct edid *edid = NULL; |
3228 | 3239 | ||
3229 | intel_runtime_pm_get(dev_priv); | 3240 | intel_runtime_pm_get(dev_priv); |
3230 | 3241 | ||
3242 | power_domain = intel_display_port_power_domain(intel_encoder); | ||
3243 | intel_display_power_get(dev_priv, power_domain); | ||
3244 | |||
3231 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", | 3245 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", |
3232 | connector->base.id, drm_get_connector_name(connector)); | 3246 | connector->base.id, drm_get_connector_name(connector)); |
3233 | 3247 | ||
@@ -3258,21 +3272,32 @@ intel_dp_detect(struct drm_connector *connector, bool force) | |||
3258 | status = connector_status_connected; | 3272 | status = connector_status_connected; |
3259 | 3273 | ||
3260 | out: | 3274 | out: |
3275 | intel_display_power_put(dev_priv, power_domain); | ||
3276 | |||
3261 | intel_runtime_pm_put(dev_priv); | 3277 | intel_runtime_pm_put(dev_priv); |
3278 | |||
3262 | return status; | 3279 | return status; |
3263 | } | 3280 | } |
3264 | 3281 | ||
3265 | static int intel_dp_get_modes(struct drm_connector *connector) | 3282 | static int intel_dp_get_modes(struct drm_connector *connector) |
3266 | { | 3283 | { |
3267 | struct intel_dp *intel_dp = intel_attached_dp(connector); | 3284 | struct intel_dp *intel_dp = intel_attached_dp(connector); |
3285 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | ||
3286 | struct intel_encoder *intel_encoder = &intel_dig_port->base; | ||
3268 | struct intel_connector *intel_connector = to_intel_connector(connector); | 3287 | struct intel_connector *intel_connector = to_intel_connector(connector); |
3269 | struct drm_device *dev = connector->dev; | 3288 | struct drm_device *dev = connector->dev; |
3289 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3290 | enum intel_display_power_domain power_domain; | ||
3270 | int ret; | 3291 | int ret; |
3271 | 3292 | ||
3272 | /* We should parse the EDID data and find out if it has an audio sink | 3293 | /* We should parse the EDID data and find out if it has an audio sink |
3273 | */ | 3294 | */ |
3274 | 3295 | ||
3296 | power_domain = intel_display_port_power_domain(intel_encoder); | ||
3297 | intel_display_power_get(dev_priv, power_domain); | ||
3298 | |||
3275 | ret = intel_dp_get_edid_modes(connector, &intel_dp->adapter); | 3299 | ret = intel_dp_get_edid_modes(connector, &intel_dp->adapter); |
3300 | intel_display_power_put(dev_priv, power_domain); | ||
3276 | if (ret) | 3301 | if (ret) |
3277 | return ret; | 3302 | return ret; |
3278 | 3303 | ||
@@ -3293,15 +3318,25 @@ static bool | |||
3293 | intel_dp_detect_audio(struct drm_connector *connector) | 3318 | intel_dp_detect_audio(struct drm_connector *connector) |
3294 | { | 3319 | { |
3295 | struct intel_dp *intel_dp = intel_attached_dp(connector); | 3320 | struct intel_dp *intel_dp = intel_attached_dp(connector); |
3321 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | ||
3322 | struct intel_encoder *intel_encoder = &intel_dig_port->base; | ||
3323 | struct drm_device *dev = connector->dev; | ||
3324 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3325 | enum intel_display_power_domain power_domain; | ||
3296 | struct edid *edid; | 3326 | struct edid *edid; |
3297 | bool has_audio = false; | 3327 | bool has_audio = false; |
3298 | 3328 | ||
3329 | power_domain = intel_display_port_power_domain(intel_encoder); | ||
3330 | intel_display_power_get(dev_priv, power_domain); | ||
3331 | |||
3299 | edid = intel_dp_get_edid(connector, &intel_dp->adapter); | 3332 | edid = intel_dp_get_edid(connector, &intel_dp->adapter); |
3300 | if (edid) { | 3333 | if (edid) { |
3301 | has_audio = drm_detect_monitor_audio(edid); | 3334 | has_audio = drm_detect_monitor_audio(edid); |
3302 | kfree(edid); | 3335 | kfree(edid); |
3303 | } | 3336 | } |
3304 | 3337 | ||
3338 | intel_display_power_put(dev_priv, power_domain); | ||
3339 | |||
3305 | return has_audio; | 3340 | return has_audio; |
3306 | } | 3341 | } |
3307 | 3342 | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a4ffc021c317..9c7090590776 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -609,6 +609,8 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi) | |||
609 | /* i915_irq.c */ | 609 | /* i915_irq.c */ |
610 | bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, | 610 | bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, |
611 | enum pipe pipe, bool enable); | 611 | enum pipe pipe, bool enable); |
612 | bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, | ||
613 | enum pipe pipe, bool enable); | ||
612 | bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev, | 614 | bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev, |
613 | enum transcoder pch_transcoder, | 615 | enum transcoder pch_transcoder, |
614 | bool enable); | 616 | bool enable); |
@@ -732,7 +734,9 @@ ironlake_check_encoder_dotclock(const struct intel_crtc_config *pipe_config, | |||
732 | bool intel_crtc_active(struct drm_crtc *crtc); | 734 | bool intel_crtc_active(struct drm_crtc *crtc); |
733 | void hsw_enable_ips(struct intel_crtc *crtc); | 735 | void hsw_enable_ips(struct intel_crtc *crtc); |
734 | void hsw_disable_ips(struct intel_crtc *crtc); | 736 | void hsw_disable_ips(struct intel_crtc *crtc); |
735 | void intel_display_set_init_power(struct drm_device *dev, bool enable); | 737 | void intel_display_set_init_power(struct drm_i915_private *dev, bool enable); |
738 | enum intel_display_power_domain | ||
739 | intel_display_port_power_domain(struct intel_encoder *intel_encoder); | ||
736 | int valleyview_get_vco(struct drm_i915_private *dev_priv); | 740 | int valleyview_get_vco(struct drm_i915_private *dev_priv); |
737 | void intel_mode_from_pipe_config(struct drm_display_mode *mode, | 741 | void intel_mode_from_pipe_config(struct drm_display_mode *mode, |
738 | struct intel_crtc_config *pipe_config); | 742 | struct intel_crtc_config *pipe_config); |
@@ -871,18 +875,17 @@ bool intel_fbc_enabled(struct drm_device *dev); | |||
871 | void intel_update_fbc(struct drm_device *dev); | 875 | void intel_update_fbc(struct drm_device *dev); |
872 | void intel_gpu_ips_init(struct drm_i915_private *dev_priv); | 876 | void intel_gpu_ips_init(struct drm_i915_private *dev_priv); |
873 | void intel_gpu_ips_teardown(void); | 877 | void intel_gpu_ips_teardown(void); |
874 | int intel_power_domains_init(struct drm_device *dev); | 878 | int intel_power_domains_init(struct drm_i915_private *); |
875 | void intel_power_domains_remove(struct drm_device *dev); | 879 | void intel_power_domains_remove(struct drm_i915_private *); |
876 | bool intel_display_power_enabled(struct drm_device *dev, | 880 | bool intel_display_power_enabled(struct drm_i915_private *dev_priv, |
877 | enum intel_display_power_domain domain); | 881 | enum intel_display_power_domain domain); |
878 | bool intel_display_power_enabled_sw(struct drm_device *dev, | 882 | bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, |
879 | enum intel_display_power_domain domain); | 883 | enum intel_display_power_domain domain); |
880 | void intel_display_power_get(struct drm_device *dev, | 884 | void intel_display_power_get(struct drm_i915_private *dev_priv, |
881 | enum intel_display_power_domain domain); | 885 | enum intel_display_power_domain domain); |
882 | void intel_display_power_put(struct drm_device *dev, | 886 | void intel_display_power_put(struct drm_i915_private *dev_priv, |
883 | enum intel_display_power_domain domain); | 887 | enum intel_display_power_domain domain); |
884 | void intel_power_domains_init_hw(struct drm_device *dev); | 888 | void intel_power_domains_init_hw(struct drm_i915_private *dev_priv); |
885 | void intel_set_power_well(struct drm_device *dev, bool enable); | ||
886 | void intel_enable_gt_powersave(struct drm_device *dev); | 889 | void intel_enable_gt_powersave(struct drm_device *dev); |
887 | void intel_disable_gt_powersave(struct drm_device *dev); | 890 | void intel_disable_gt_powersave(struct drm_device *dev); |
888 | void ironlake_teardown_rc6(struct drm_device *dev); | 891 | void ironlake_teardown_rc6(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 3ee1db1407b0..cf7322e95278 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c | |||
@@ -243,11 +243,16 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, | |||
243 | enum pipe *pipe) | 243 | enum pipe *pipe) |
244 | { | 244 | { |
245 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; | 245 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
246 | enum intel_display_power_domain power_domain; | ||
246 | u32 port, func; | 247 | u32 port, func; |
247 | enum pipe p; | 248 | enum pipe p; |
248 | 249 | ||
249 | DRM_DEBUG_KMS("\n"); | 250 | DRM_DEBUG_KMS("\n"); |
250 | 251 | ||
252 | power_domain = intel_display_port_power_domain(encoder); | ||
253 | if (!intel_display_power_enabled(dev_priv, power_domain)) | ||
254 | return false; | ||
255 | |||
251 | /* XXX: this only works for one DSI output */ | 256 | /* XXX: this only works for one DSI output */ |
252 | for (p = PIPE_A; p <= PIPE_B; p++) { | 257 | for (p = PIPE_A; p <= PIPE_B; p++) { |
253 | port = I915_READ(MIPI_PORT_CTRL(p)); | 258 | port = I915_READ(MIPI_PORT_CTRL(p)); |
@@ -488,8 +493,19 @@ static enum drm_connector_status | |||
488 | intel_dsi_detect(struct drm_connector *connector, bool force) | 493 | intel_dsi_detect(struct drm_connector *connector, bool force) |
489 | { | 494 | { |
490 | struct intel_dsi *intel_dsi = intel_attached_dsi(connector); | 495 | struct intel_dsi *intel_dsi = intel_attached_dsi(connector); |
496 | struct intel_encoder *intel_encoder = &intel_dsi->base; | ||
497 | enum intel_display_power_domain power_domain; | ||
498 | enum drm_connector_status connector_status; | ||
499 | struct drm_i915_private *dev_priv = intel_encoder->base.dev->dev_private; | ||
500 | |||
491 | DRM_DEBUG_KMS("\n"); | 501 | DRM_DEBUG_KMS("\n"); |
492 | return intel_dsi->dev.dev_ops->detect(&intel_dsi->dev); | 502 | power_domain = intel_display_port_power_domain(intel_encoder); |
503 | |||
504 | intel_display_power_get(dev_priv, power_domain); | ||
505 | connector_status = intel_dsi->dev.dev_ops->detect(&intel_dsi->dev); | ||
506 | intel_display_power_put(dev_priv, power_domain); | ||
507 | |||
508 | return connector_status; | ||
493 | } | 509 | } |
494 | 510 | ||
495 | static int intel_dsi_get_modes(struct drm_connector *connector) | 511 | static int intel_dsi_get_modes(struct drm_connector *connector) |
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 19be4bfbcc59..6b5beed28d70 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c | |||
@@ -289,7 +289,27 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, | |||
289 | struct drm_device *dev = fb_helper->dev; | 289 | struct drm_device *dev = fb_helper->dev; |
290 | int i, j; | 290 | int i, j; |
291 | bool *save_enabled; | 291 | bool *save_enabled; |
292 | bool any_enabled = false; | 292 | bool fallback = true; |
293 | int num_connectors_enabled = 0; | ||
294 | int num_connectors_detected = 0; | ||
295 | |||
296 | /* | ||
297 | * If the user specified any force options, just bail here | ||
298 | * and use that config. | ||
299 | */ | ||
300 | for (i = 0; i < fb_helper->connector_count; i++) { | ||
301 | struct drm_fb_helper_connector *fb_conn; | ||
302 | struct drm_connector *connector; | ||
303 | |||
304 | fb_conn = fb_helper->connector_info[i]; | ||
305 | connector = fb_conn->connector; | ||
306 | |||
307 | if (!enabled[i]) | ||
308 | continue; | ||
309 | |||
310 | if (connector->force != DRM_FORCE_UNSPECIFIED) | ||
311 | return false; | ||
312 | } | ||
293 | 313 | ||
294 | save_enabled = kcalloc(dev->mode_config.num_connector, sizeof(bool), | 314 | save_enabled = kcalloc(dev->mode_config.num_connector, sizeof(bool), |
295 | GFP_KERNEL); | 315 | GFP_KERNEL); |
@@ -306,6 +326,10 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, | |||
306 | 326 | ||
307 | fb_conn = fb_helper->connector_info[i]; | 327 | fb_conn = fb_helper->connector_info[i]; |
308 | connector = fb_conn->connector; | 328 | connector = fb_conn->connector; |
329 | |||
330 | if (connector->status == connector_status_connected) | ||
331 | num_connectors_detected++; | ||
332 | |||
309 | if (!enabled[i]) { | 333 | if (!enabled[i]) { |
310 | DRM_DEBUG_KMS("connector %d not enabled, skipping\n", | 334 | DRM_DEBUG_KMS("connector %d not enabled, skipping\n", |
311 | connector->base.id); | 335 | connector->base.id); |
@@ -320,6 +344,8 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, | |||
320 | continue; | 344 | continue; |
321 | } | 345 | } |
322 | 346 | ||
347 | num_connectors_enabled++; | ||
348 | |||
323 | new_crtc = intel_fb_helper_crtc(fb_helper, encoder->crtc); | 349 | new_crtc = intel_fb_helper_crtc(fb_helper, encoder->crtc); |
324 | 350 | ||
325 | /* | 351 | /* |
@@ -329,7 +355,8 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, | |||
329 | */ | 355 | */ |
330 | for (j = 0; j < fb_helper->connector_count; j++) { | 356 | for (j = 0; j < fb_helper->connector_count; j++) { |
331 | if (crtcs[j] == new_crtc) { | 357 | if (crtcs[j] == new_crtc) { |
332 | any_enabled = false; | 358 | DRM_DEBUG_KMS("fallback: cloned configuration\n"); |
359 | fallback = true; | ||
333 | goto out; | 360 | goto out; |
334 | } | 361 | } |
335 | } | 362 | } |
@@ -372,11 +399,25 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, | |||
372 | encoder->crtc->base.id, | 399 | encoder->crtc->base.id, |
373 | modes[i]->name); | 400 | modes[i]->name); |
374 | 401 | ||
375 | any_enabled = true; | 402 | fallback = false; |
403 | } | ||
404 | |||
405 | /* | ||
406 | * If the BIOS didn't enable everything it could, fall back to have the | ||
407 | * same user experiencing of lighting up as much as possible like the | ||
408 | * fbdev helper library. | ||
409 | */ | ||
410 | if (num_connectors_enabled != num_connectors_detected && | ||
411 | num_connectors_enabled < INTEL_INFO(dev)->num_pipes) { | ||
412 | DRM_DEBUG_KMS("fallback: Not all outputs enabled\n"); | ||
413 | DRM_DEBUG_KMS("Enabled: %i, detected: %i\n", num_connectors_enabled, | ||
414 | num_connectors_detected); | ||
415 | fallback = true; | ||
376 | } | 416 | } |
377 | 417 | ||
378 | out: | 418 | out: |
379 | if (!any_enabled) { | 419 | if (fallback) { |
420 | DRM_DEBUG_KMS("Not using firmware configuration\n"); | ||
380 | memcpy(enabled, save_enabled, dev->mode_config.num_connector); | 421 | memcpy(enabled, save_enabled, dev->mode_config.num_connector); |
381 | kfree(save_enabled); | 422 | kfree(save_enabled); |
382 | return false; | 423 | return false; |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 98d68ab04de4..f410cc03e08a 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -667,8 +667,13 @@ static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder, | |||
667 | struct drm_device *dev = encoder->base.dev; | 667 | struct drm_device *dev = encoder->base.dev; |
668 | struct drm_i915_private *dev_priv = dev->dev_private; | 668 | struct drm_i915_private *dev_priv = dev->dev_private; |
669 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); | 669 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); |
670 | enum intel_display_power_domain power_domain; | ||
670 | u32 tmp; | 671 | u32 tmp; |
671 | 672 | ||
673 | power_domain = intel_display_port_power_domain(encoder); | ||
674 | if (!intel_display_power_enabled(dev_priv, power_domain)) | ||
675 | return false; | ||
676 | |||
672 | tmp = I915_READ(intel_hdmi->hdmi_reg); | 677 | tmp = I915_READ(intel_hdmi->hdmi_reg); |
673 | 678 | ||
674 | if (!(tmp & SDVO_ENABLE)) | 679 | if (!(tmp & SDVO_ENABLE)) |
@@ -909,11 +914,15 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) | |||
909 | struct intel_encoder *intel_encoder = &intel_dig_port->base; | 914 | struct intel_encoder *intel_encoder = &intel_dig_port->base; |
910 | struct drm_i915_private *dev_priv = dev->dev_private; | 915 | struct drm_i915_private *dev_priv = dev->dev_private; |
911 | struct edid *edid; | 916 | struct edid *edid; |
917 | enum intel_display_power_domain power_domain; | ||
912 | enum drm_connector_status status = connector_status_disconnected; | 918 | enum drm_connector_status status = connector_status_disconnected; |
913 | 919 | ||
914 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", | 920 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", |
915 | connector->base.id, drm_get_connector_name(connector)); | 921 | connector->base.id, drm_get_connector_name(connector)); |
916 | 922 | ||
923 | power_domain = intel_display_port_power_domain(intel_encoder); | ||
924 | intel_display_power_get(dev_priv, power_domain); | ||
925 | |||
917 | intel_hdmi->has_hdmi_sink = false; | 926 | intel_hdmi->has_hdmi_sink = false; |
918 | intel_hdmi->has_audio = false; | 927 | intel_hdmi->has_audio = false; |
919 | intel_hdmi->rgb_quant_range_selectable = false; | 928 | intel_hdmi->rgb_quant_range_selectable = false; |
@@ -941,31 +950,48 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) | |||
941 | intel_encoder->type = INTEL_OUTPUT_HDMI; | 950 | intel_encoder->type = INTEL_OUTPUT_HDMI; |
942 | } | 951 | } |
943 | 952 | ||
953 | intel_display_power_put(dev_priv, power_domain); | ||
954 | |||
944 | return status; | 955 | return status; |
945 | } | 956 | } |
946 | 957 | ||
947 | static int intel_hdmi_get_modes(struct drm_connector *connector) | 958 | static int intel_hdmi_get_modes(struct drm_connector *connector) |
948 | { | 959 | { |
949 | struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); | 960 | struct intel_encoder *intel_encoder = intel_attached_encoder(connector); |
961 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&intel_encoder->base); | ||
950 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 962 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
963 | enum intel_display_power_domain power_domain; | ||
964 | int ret; | ||
951 | 965 | ||
952 | /* We should parse the EDID data and find out if it's an HDMI sink so | 966 | /* We should parse the EDID data and find out if it's an HDMI sink so |
953 | * we can send audio to it. | 967 | * we can send audio to it. |
954 | */ | 968 | */ |
955 | 969 | ||
956 | return intel_ddc_get_modes(connector, | 970 | power_domain = intel_display_port_power_domain(intel_encoder); |
971 | intel_display_power_get(dev_priv, power_domain); | ||
972 | |||
973 | ret = intel_ddc_get_modes(connector, | ||
957 | intel_gmbus_get_adapter(dev_priv, | 974 | intel_gmbus_get_adapter(dev_priv, |
958 | intel_hdmi->ddc_bus)); | 975 | intel_hdmi->ddc_bus)); |
976 | |||
977 | intel_display_power_put(dev_priv, power_domain); | ||
978 | |||
979 | return ret; | ||
959 | } | 980 | } |
960 | 981 | ||
961 | static bool | 982 | static bool |
962 | intel_hdmi_detect_audio(struct drm_connector *connector) | 983 | intel_hdmi_detect_audio(struct drm_connector *connector) |
963 | { | 984 | { |
964 | struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); | 985 | struct intel_encoder *intel_encoder = intel_attached_encoder(connector); |
986 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&intel_encoder->base); | ||
965 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 987 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
988 | enum intel_display_power_domain power_domain; | ||
966 | struct edid *edid; | 989 | struct edid *edid; |
967 | bool has_audio = false; | 990 | bool has_audio = false; |
968 | 991 | ||
992 | power_domain = intel_display_port_power_domain(intel_encoder); | ||
993 | intel_display_power_get(dev_priv, power_domain); | ||
994 | |||
969 | edid = drm_get_edid(connector, | 995 | edid = drm_get_edid(connector, |
970 | intel_gmbus_get_adapter(dev_priv, | 996 | intel_gmbus_get_adapter(dev_priv, |
971 | intel_hdmi->ddc_bus)); | 997 | intel_hdmi->ddc_bus)); |
@@ -975,6 +1001,8 @@ intel_hdmi_detect_audio(struct drm_connector *connector) | |||
975 | kfree(edid); | 1001 | kfree(edid); |
976 | } | 1002 | } |
977 | 1003 | ||
1004 | intel_display_power_put(dev_priv, power_domain); | ||
1005 | |||
978 | return has_audio; | 1006 | return has_audio; |
979 | } | 1007 | } |
980 | 1008 | ||
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index ac519cb46f22..312961a8472e 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -1076,7 +1076,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, | |||
1076 | mutex_lock(&dev->struct_mutex); | 1076 | mutex_lock(&dev->struct_mutex); |
1077 | 1077 | ||
1078 | if (new_bo->tiling_mode) { | 1078 | if (new_bo->tiling_mode) { |
1079 | DRM_ERROR("buffer used for overlay image can not be tiled\n"); | 1079 | DRM_DEBUG_KMS("buffer used for overlay image can not be tiled\n"); |
1080 | ret = -EINVAL; | 1080 | ret = -EINVAL; |
1081 | goto out_unlock; | 1081 | goto out_unlock; |
1082 | } | 1082 | } |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index a6b877a4a916..fc96e611a8a7 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -294,11 +294,14 @@ static void gen7_enable_fbc(struct drm_crtc *crtc) | |||
294 | 294 | ||
295 | if (IS_IVYBRIDGE(dev)) { | 295 | if (IS_IVYBRIDGE(dev)) { |
296 | /* WaFbcAsynchFlipDisableFbcQueue:ivb */ | 296 | /* WaFbcAsynchFlipDisableFbcQueue:ivb */ |
297 | I915_WRITE(ILK_DISPLAY_CHICKEN1, ILK_FBCQ_DIS); | 297 | I915_WRITE(ILK_DISPLAY_CHICKEN1, |
298 | I915_READ(ILK_DISPLAY_CHICKEN1) | | ||
299 | ILK_FBCQ_DIS); | ||
298 | } else { | 300 | } else { |
299 | /* WaFbcAsynchFlipDisableFbcQueue:hsw */ | 301 | /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ |
300 | I915_WRITE(HSW_PIPE_SLICE_CHICKEN_1(intel_crtc->pipe), | 302 | I915_WRITE(CHICKEN_PIPESL_1(intel_crtc->pipe), |
301 | HSW_BYPASS_FBC_QUEUE); | 303 | I915_READ(CHICKEN_PIPESL_1(intel_crtc->pipe)) | |
304 | HSW_FBCQ_DIS); | ||
302 | } | 305 | } |
303 | 306 | ||
304 | I915_WRITE(SNB_DPFC_CTL_SA, | 307 | I915_WRITE(SNB_DPFC_CTL_SA, |
@@ -540,7 +543,7 @@ void intel_update_fbc(struct drm_device *dev) | |||
540 | DRM_DEBUG_KMS("mode too large for compression, disabling\n"); | 543 | DRM_DEBUG_KMS("mode too large for compression, disabling\n"); |
541 | goto out_disable; | 544 | goto out_disable; |
542 | } | 545 | } |
543 | if ((INTEL_INFO(dev)->gen < 4 || IS_HASWELL(dev)) && | 546 | if ((INTEL_INFO(dev)->gen < 4 || HAS_DDI(dev)) && |
544 | intel_crtc->plane != PLANE_A) { | 547 | intel_crtc->plane != PLANE_A) { |
545 | if (set_no_fbc_reason(dev_priv, FBC_BAD_PLANE)) | 548 | if (set_no_fbc_reason(dev_priv, FBC_BAD_PLANE)) |
546 | DRM_DEBUG_KMS("plane not A, disabling compression\n"); | 549 | DRM_DEBUG_KMS("plane not A, disabling compression\n"); |
@@ -1131,7 +1134,7 @@ static bool g4x_compute_wm0(struct drm_device *dev, | |||
1131 | *plane_wm = display->max_wm; | 1134 | *plane_wm = display->max_wm; |
1132 | 1135 | ||
1133 | /* Use the large buffer method to calculate cursor watermark */ | 1136 | /* Use the large buffer method to calculate cursor watermark */ |
1134 | line_time_us = ((htotal * 1000) / clock); | 1137 | line_time_us = max(htotal * 1000 / clock, 1); |
1135 | line_count = (cursor_latency_ns / line_time_us + 1000) / 1000; | 1138 | line_count = (cursor_latency_ns / line_time_us + 1000) / 1000; |
1136 | entries = line_count * 64 * pixel_size; | 1139 | entries = line_count * 64 * pixel_size; |
1137 | tlb_miss = cursor->fifo_size*cursor->cacheline_size - hdisplay * 8; | 1140 | tlb_miss = cursor->fifo_size*cursor->cacheline_size - hdisplay * 8; |
@@ -1207,7 +1210,7 @@ static bool g4x_compute_srwm(struct drm_device *dev, | |||
1207 | hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; | 1210 | hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; |
1208 | pixel_size = crtc->fb->bits_per_pixel / 8; | 1211 | pixel_size = crtc->fb->bits_per_pixel / 8; |
1209 | 1212 | ||
1210 | line_time_us = (htotal * 1000) / clock; | 1213 | line_time_us = max(htotal * 1000 / clock, 1); |
1211 | line_count = (latency_ns / line_time_us + 1000) / 1000; | 1214 | line_count = (latency_ns / line_time_us + 1000) / 1000; |
1212 | line_size = hdisplay * pixel_size; | 1215 | line_size = hdisplay * pixel_size; |
1213 | 1216 | ||
@@ -1440,7 +1443,7 @@ static void i965_update_wm(struct drm_crtc *unused_crtc) | |||
1440 | unsigned long line_time_us; | 1443 | unsigned long line_time_us; |
1441 | int entries; | 1444 | int entries; |
1442 | 1445 | ||
1443 | line_time_us = ((htotal * 1000) / clock); | 1446 | line_time_us = max(htotal * 1000 / clock, 1); |
1444 | 1447 | ||
1445 | /* Use ns/us then divide to preserve precision */ | 1448 | /* Use ns/us then divide to preserve precision */ |
1446 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * | 1449 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * |
@@ -1566,7 +1569,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) | |||
1566 | unsigned long line_time_us; | 1569 | unsigned long line_time_us; |
1567 | int entries; | 1570 | int entries; |
1568 | 1571 | ||
1569 | line_time_us = (htotal * 1000) / clock; | 1572 | line_time_us = max(htotal * 1000 / clock, 1); |
1570 | 1573 | ||
1571 | /* Use ns/us then divide to preserve precision */ | 1574 | /* Use ns/us then divide to preserve precision */ |
1572 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * | 1575 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * |
@@ -4661,6 +4664,17 @@ static void gen6_init_clock_gating(struct drm_device *dev) | |||
4661 | I915_WRITE(GEN6_GT_MODE, | 4664 | I915_WRITE(GEN6_GT_MODE, |
4662 | _MASKED_BIT_ENABLE(GEN6_TD_FOUR_ROW_DISPATCH_DISABLE)); | 4665 | _MASKED_BIT_ENABLE(GEN6_TD_FOUR_ROW_DISPATCH_DISABLE)); |
4663 | 4666 | ||
4667 | /* | ||
4668 | * BSpec recoomends 8x4 when MSAA is used, | ||
4669 | * however in practice 16x4 seems fastest. | ||
4670 | * | ||
4671 | * Note that PS/WM thread counts depend on the WIZ hashing | ||
4672 | * disable bit, which we don't touch here, but it's good | ||
4673 | * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). | ||
4674 | */ | ||
4675 | I915_WRITE(GEN6_GT_MODE, | ||
4676 | GEN6_WIZ_HASHING_MASK | GEN6_WIZ_HASHING_16x4); | ||
4677 | |||
4664 | ilk_init_lp_watermarks(dev); | 4678 | ilk_init_lp_watermarks(dev); |
4665 | 4679 | ||
4666 | I915_WRITE(CACHE_MODE_0, | 4680 | I915_WRITE(CACHE_MODE_0, |
@@ -4688,9 +4702,9 @@ static void gen6_init_clock_gating(struct drm_device *dev) | |||
4688 | GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | | 4702 | GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | |
4689 | GEN6_RCCUNIT_CLOCK_GATE_DISABLE); | 4703 | GEN6_RCCUNIT_CLOCK_GATE_DISABLE); |
4690 | 4704 | ||
4691 | /* Bspec says we need to always set all mask bits. */ | 4705 | /* WaStripsFansDisableFastClipPerformanceFix:snb */ |
4692 | I915_WRITE(_3D_CHICKEN3, (0xFFFF << 16) | | 4706 | I915_WRITE(_3D_CHICKEN3, |
4693 | _3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL); | 4707 | _MASKED_BIT_ENABLE(_3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL)); |
4694 | 4708 | ||
4695 | /* | 4709 | /* |
4696 | * Bspec says: | 4710 | * Bspec says: |
@@ -4724,11 +4738,6 @@ static void gen6_init_clock_gating(struct drm_device *dev) | |||
4724 | 4738 | ||
4725 | g4x_disable_trickle_feed(dev); | 4739 | g4x_disable_trickle_feed(dev); |
4726 | 4740 | ||
4727 | /* The default value should be 0x200 according to docs, but the two | ||
4728 | * platforms I checked have a 0 for this. (Maybe BIOS overrides?) */ | ||
4729 | I915_WRITE(GEN6_GT_MODE, _MASKED_BIT_DISABLE(0xffff)); | ||
4730 | I915_WRITE(GEN6_GT_MODE, _MASKED_BIT_ENABLE(GEN6_GT_MODE_HI)); | ||
4731 | |||
4732 | cpt_init_clock_gating(dev); | 4741 | cpt_init_clock_gating(dev); |
4733 | 4742 | ||
4734 | gen6_check_mch_setup(dev); | 4743 | gen6_check_mch_setup(dev); |
@@ -4786,7 +4795,7 @@ static void lpt_suspend_hw(struct drm_device *dev) | |||
4786 | static void gen8_init_clock_gating(struct drm_device *dev) | 4795 | static void gen8_init_clock_gating(struct drm_device *dev) |
4787 | { | 4796 | { |
4788 | struct drm_i915_private *dev_priv = dev->dev_private; | 4797 | struct drm_i915_private *dev_priv = dev->dev_private; |
4789 | enum pipe i; | 4798 | enum pipe pipe; |
4790 | 4799 | ||
4791 | I915_WRITE(WM3_LP_ILK, 0); | 4800 | I915_WRITE(WM3_LP_ILK, 0); |
4792 | I915_WRITE(WM2_LP_ILK, 0); | 4801 | I915_WRITE(WM2_LP_ILK, 0); |
@@ -4795,6 +4804,15 @@ static void gen8_init_clock_gating(struct drm_device *dev) | |||
4795 | /* FIXME(BDW): Check all the w/a, some might only apply to | 4804 | /* FIXME(BDW): Check all the w/a, some might only apply to |
4796 | * pre-production hw. */ | 4805 | * pre-production hw. */ |
4797 | 4806 | ||
4807 | /* WaDisablePartialInstShootdown:bdw */ | ||
4808 | I915_WRITE(GEN8_ROW_CHICKEN, | ||
4809 | _MASKED_BIT_ENABLE(PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE)); | ||
4810 | |||
4811 | /* WaDisableThreadStallDopClockGating:bdw */ | ||
4812 | /* FIXME: Unclear whether we really need this on production bdw. */ | ||
4813 | I915_WRITE(GEN8_ROW_CHICKEN, | ||
4814 | _MASKED_BIT_ENABLE(STALL_DOP_GATING_DISABLE)); | ||
4815 | |||
4798 | /* | 4816 | /* |
4799 | * This GEN8_CENTROID_PIXEL_OPT_DIS W/A is only needed for | 4817 | * This GEN8_CENTROID_PIXEL_OPT_DIS W/A is only needed for |
4800 | * pre-production hardware | 4818 | * pre-production hardware |
@@ -4822,10 +4840,10 @@ static void gen8_init_clock_gating(struct drm_device *dev) | |||
4822 | I915_READ(CHICKEN_PAR1_1) | DPA_MASK_VBLANK_SRD); | 4840 | I915_READ(CHICKEN_PAR1_1) | DPA_MASK_VBLANK_SRD); |
4823 | 4841 | ||
4824 | /* WaPsrDPRSUnmaskVBlankInSRD:bdw */ | 4842 | /* WaPsrDPRSUnmaskVBlankInSRD:bdw */ |
4825 | for_each_pipe(i) { | 4843 | for_each_pipe(pipe) { |
4826 | I915_WRITE(CHICKEN_PIPESL_1(i), | 4844 | I915_WRITE(CHICKEN_PIPESL_1(pipe), |
4827 | I915_READ(CHICKEN_PIPESL_1(i) | | 4845 | I915_READ(CHICKEN_PIPESL_1(pipe)) | |
4828 | DPRS_MASK_VBLANK_SRD)); | 4846 | BDW_DPRS_MASK_VBLANK_SRD); |
4829 | } | 4847 | } |
4830 | 4848 | ||
4831 | /* Use Force Non-Coherent whenever executing a 3D context. This is a | 4849 | /* Use Force Non-Coherent whenever executing a 3D context. This is a |
@@ -4841,6 +4859,24 @@ static void gen8_init_clock_gating(struct drm_device *dev) | |||
4841 | I915_WRITE(GEN7_FF_THREAD_MODE, | 4859 | I915_WRITE(GEN7_FF_THREAD_MODE, |
4842 | I915_READ(GEN7_FF_THREAD_MODE) & | 4860 | I915_READ(GEN7_FF_THREAD_MODE) & |
4843 | ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME)); | 4861 | ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME)); |
4862 | |||
4863 | /* | ||
4864 | * BSpec recommends 8x4 when MSAA is used, | ||
4865 | * however in practice 16x4 seems fastest. | ||
4866 | * | ||
4867 | * Note that PS/WM thread counts depend on the WIZ hashing | ||
4868 | * disable bit, which we don't touch here, but it's good | ||
4869 | * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). | ||
4870 | */ | ||
4871 | I915_WRITE(GEN7_GT_MODE, | ||
4872 | GEN6_WIZ_HASHING_MASK | GEN6_WIZ_HASHING_16x4); | ||
4873 | |||
4874 | I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL, | ||
4875 | _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE)); | ||
4876 | |||
4877 | /* WaDisableSDEUnitClockGating:bdw */ | ||
4878 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | | ||
4879 | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); | ||
4844 | } | 4880 | } |
4845 | 4881 | ||
4846 | static void haswell_init_clock_gating(struct drm_device *dev) | 4882 | static void haswell_init_clock_gating(struct drm_device *dev) |
@@ -4871,6 +4907,17 @@ static void haswell_init_clock_gating(struct drm_device *dev) | |||
4871 | I915_WRITE(CACHE_MODE_1, | 4907 | I915_WRITE(CACHE_MODE_1, |
4872 | _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); | 4908 | _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); |
4873 | 4909 | ||
4910 | /* | ||
4911 | * BSpec recommends 8x4 when MSAA is used, | ||
4912 | * however in practice 16x4 seems fastest. | ||
4913 | * | ||
4914 | * Note that PS/WM thread counts depend on the WIZ hashing | ||
4915 | * disable bit, which we don't touch here, but it's good | ||
4916 | * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). | ||
4917 | */ | ||
4918 | I915_WRITE(GEN7_GT_MODE, | ||
4919 | GEN6_WIZ_HASHING_MASK | GEN6_WIZ_HASHING_16x4); | ||
4920 | |||
4874 | /* WaSwitchSolVfFArbitrationPriority:hsw */ | 4921 | /* WaSwitchSolVfFArbitrationPriority:hsw */ |
4875 | I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); | 4922 | I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); |
4876 | 4923 | ||
@@ -4944,14 +4991,27 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) | |||
4944 | 4991 | ||
4945 | gen7_setup_fixed_func_scheduler(dev_priv); | 4992 | gen7_setup_fixed_func_scheduler(dev_priv); |
4946 | 4993 | ||
4947 | /* enable HiZ Raw Stall Optimization */ | 4994 | if (0) { /* causes HiZ corruption on ivb:gt1 */ |
4948 | I915_WRITE(CACHE_MODE_0_GEN7, | 4995 | /* enable HiZ Raw Stall Optimization */ |
4949 | _MASKED_BIT_DISABLE(HIZ_RAW_STALL_OPT_DISABLE)); | 4996 | I915_WRITE(CACHE_MODE_0_GEN7, |
4997 | _MASKED_BIT_DISABLE(HIZ_RAW_STALL_OPT_DISABLE)); | ||
4998 | } | ||
4950 | 4999 | ||
4951 | /* WaDisable4x2SubspanOptimization:ivb */ | 5000 | /* WaDisable4x2SubspanOptimization:ivb */ |
4952 | I915_WRITE(CACHE_MODE_1, | 5001 | I915_WRITE(CACHE_MODE_1, |
4953 | _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); | 5002 | _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); |
4954 | 5003 | ||
5004 | /* | ||
5005 | * BSpec recommends 8x4 when MSAA is used, | ||
5006 | * however in practice 16x4 seems fastest. | ||
5007 | * | ||
5008 | * Note that PS/WM thread counts depend on the WIZ hashing | ||
5009 | * disable bit, which we don't touch here, but it's good | ||
5010 | * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). | ||
5011 | */ | ||
5012 | I915_WRITE(GEN7_GT_MODE, | ||
5013 | GEN6_WIZ_HASHING_MASK | GEN6_WIZ_HASHING_16x4); | ||
5014 | |||
4955 | snpcr = I915_READ(GEN6_MBCUNIT_SNPCR); | 5015 | snpcr = I915_READ(GEN6_MBCUNIT_SNPCR); |
4956 | snpcr &= ~GEN6_MBC_SNPCR_MASK; | 5016 | snpcr &= ~GEN6_MBC_SNPCR_MASK; |
4957 | snpcr |= GEN6_MBC_SNPCR_MED; | 5017 | snpcr |= GEN6_MBC_SNPCR_MED; |
@@ -5004,9 +5064,6 @@ static void valleyview_init_clock_gating(struct drm_device *dev) | |||
5004 | _MASKED_BIT_ENABLE(GEN7_MAX_PS_THREAD_DEP | | 5064 | _MASKED_BIT_ENABLE(GEN7_MAX_PS_THREAD_DEP | |
5005 | GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE)); | 5065 | GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE)); |
5006 | 5066 | ||
5007 | /* WaDisableL3CacheAging:vlv */ | ||
5008 | I915_WRITE(GEN7_L3CNTLREG1, I915_READ(GEN7_L3CNTLREG1) | GEN7_L3AGDIS); | ||
5009 | |||
5010 | /* WaForceL3Serialization:vlv */ | 5067 | /* WaForceL3Serialization:vlv */ |
5011 | I915_WRITE(GEN7_L3SQCREG4, I915_READ(GEN7_L3SQCREG4) & | 5068 | I915_WRITE(GEN7_L3SQCREG4, I915_READ(GEN7_L3SQCREG4) & |
5012 | ~L3SQ_URB_READ_CAM_MATCH_DISABLE); | 5069 | ~L3SQ_URB_READ_CAM_MATCH_DISABLE); |
@@ -5167,19 +5224,16 @@ void intel_suspend_hw(struct drm_device *dev) | |||
5167 | * enable it, so check if it's enabled and also check if we've requested it to | 5224 | * enable it, so check if it's enabled and also check if we've requested it to |
5168 | * be enabled. | 5225 | * be enabled. |
5169 | */ | 5226 | */ |
5170 | static bool hsw_power_well_enabled(struct drm_device *dev, | 5227 | static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv, |
5171 | struct i915_power_well *power_well) | 5228 | struct i915_power_well *power_well) |
5172 | { | 5229 | { |
5173 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5174 | |||
5175 | return I915_READ(HSW_PWR_WELL_DRIVER) == | 5230 | return I915_READ(HSW_PWR_WELL_DRIVER) == |
5176 | (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED); | 5231 | (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED); |
5177 | } | 5232 | } |
5178 | 5233 | ||
5179 | bool intel_display_power_enabled_sw(struct drm_device *dev, | 5234 | bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, |
5180 | enum intel_display_power_domain domain) | 5235 | enum intel_display_power_domain domain) |
5181 | { | 5236 | { |
5182 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5183 | struct i915_power_domains *power_domains; | 5237 | struct i915_power_domains *power_domains; |
5184 | 5238 | ||
5185 | power_domains = &dev_priv->power_domains; | 5239 | power_domains = &dev_priv->power_domains; |
@@ -5187,10 +5241,9 @@ bool intel_display_power_enabled_sw(struct drm_device *dev, | |||
5187 | return power_domains->domain_use_count[domain]; | 5241 | return power_domains->domain_use_count[domain]; |
5188 | } | 5242 | } |
5189 | 5243 | ||
5190 | bool intel_display_power_enabled(struct drm_device *dev, | 5244 | bool intel_display_power_enabled(struct drm_i915_private *dev_priv, |
5191 | enum intel_display_power_domain domain) | 5245 | enum intel_display_power_domain domain) |
5192 | { | 5246 | { |
5193 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5194 | struct i915_power_domains *power_domains; | 5247 | struct i915_power_domains *power_domains; |
5195 | struct i915_power_well *power_well; | 5248 | struct i915_power_well *power_well; |
5196 | bool is_enabled; | 5249 | bool is_enabled; |
@@ -5205,7 +5258,7 @@ bool intel_display_power_enabled(struct drm_device *dev, | |||
5205 | if (power_well->always_on) | 5258 | if (power_well->always_on) |
5206 | continue; | 5259 | continue; |
5207 | 5260 | ||
5208 | if (!power_well->is_enabled(dev, power_well)) { | 5261 | if (!power_well->ops->is_enabled(dev_priv, power_well)) { |
5209 | is_enabled = false; | 5262 | is_enabled = false; |
5210 | break; | 5263 | break; |
5211 | } | 5264 | } |
@@ -5215,6 +5268,12 @@ bool intel_display_power_enabled(struct drm_device *dev, | |||
5215 | return is_enabled; | 5268 | return is_enabled; |
5216 | } | 5269 | } |
5217 | 5270 | ||
5271 | /* | ||
5272 | * Starting with Haswell, we have a "Power Down Well" that can be turned off | ||
5273 | * when not needed anymore. We have 4 registers that can request the power well | ||
5274 | * to be enabled, and it will only be disabled if none of the registers is | ||
5275 | * requesting it to be enabled. | ||
5276 | */ | ||
5218 | static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv) | 5277 | static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv) |
5219 | { | 5278 | { |
5220 | struct drm_device *dev = dev_priv->dev; | 5279 | struct drm_device *dev = dev_priv->dev; |
@@ -5251,10 +5310,17 @@ static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv) | |||
5251 | } | 5310 | } |
5252 | } | 5311 | } |
5253 | 5312 | ||
5313 | static void reset_vblank_counter(struct drm_device *dev, enum pipe pipe) | ||
5314 | { | ||
5315 | assert_spin_locked(&dev->vbl_lock); | ||
5316 | |||
5317 | dev->vblank[pipe].last = 0; | ||
5318 | } | ||
5319 | |||
5254 | static void hsw_power_well_post_disable(struct drm_i915_private *dev_priv) | 5320 | static void hsw_power_well_post_disable(struct drm_i915_private *dev_priv) |
5255 | { | 5321 | { |
5256 | struct drm_device *dev = dev_priv->dev; | 5322 | struct drm_device *dev = dev_priv->dev; |
5257 | enum pipe p; | 5323 | enum pipe pipe; |
5258 | unsigned long irqflags; | 5324 | unsigned long irqflags; |
5259 | 5325 | ||
5260 | /* | 5326 | /* |
@@ -5265,16 +5331,15 @@ static void hsw_power_well_post_disable(struct drm_i915_private *dev_priv) | |||
5265 | * FIXME: Should we do this in general in drm_vblank_post_modeset? | 5331 | * FIXME: Should we do this in general in drm_vblank_post_modeset? |
5266 | */ | 5332 | */ |
5267 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | 5333 | spin_lock_irqsave(&dev->vbl_lock, irqflags); |
5268 | for_each_pipe(p) | 5334 | for_each_pipe(pipe) |
5269 | if (p != PIPE_A) | 5335 | if (pipe != PIPE_A) |
5270 | dev->vblank[p].last = 0; | 5336 | reset_vblank_counter(dev, pipe); |
5271 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | 5337 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); |
5272 | } | 5338 | } |
5273 | 5339 | ||
5274 | static void hsw_set_power_well(struct drm_device *dev, | 5340 | static void hsw_set_power_well(struct drm_i915_private *dev_priv, |
5275 | struct i915_power_well *power_well, bool enable) | 5341 | struct i915_power_well *power_well, bool enable) |
5276 | { | 5342 | { |
5277 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5278 | bool is_enabled, enable_requested; | 5343 | bool is_enabled, enable_requested; |
5279 | uint32_t tmp; | 5344 | uint32_t tmp; |
5280 | 5345 | ||
@@ -5308,35 +5373,204 @@ static void hsw_set_power_well(struct drm_device *dev, | |||
5308 | } | 5373 | } |
5309 | } | 5374 | } |
5310 | 5375 | ||
5311 | static void __intel_power_well_get(struct drm_device *dev, | 5376 | static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv, |
5312 | struct i915_power_well *power_well) | 5377 | struct i915_power_well *power_well) |
5313 | { | 5378 | { |
5314 | struct drm_i915_private *dev_priv = dev->dev_private; | 5379 | hsw_set_power_well(dev_priv, power_well, power_well->count > 0); |
5315 | 5380 | ||
5316 | if (!power_well->count++ && power_well->set) { | 5381 | /* |
5317 | hsw_disable_package_c8(dev_priv); | 5382 | * We're taking over the BIOS, so clear any requests made by it since |
5318 | power_well->set(dev, power_well, true); | 5383 | * the driver is in charge now. |
5319 | } | 5384 | */ |
5385 | if (I915_READ(HSW_PWR_WELL_BIOS) & HSW_PWR_WELL_ENABLE_REQUEST) | ||
5386 | I915_WRITE(HSW_PWR_WELL_BIOS, 0); | ||
5320 | } | 5387 | } |
5321 | 5388 | ||
5322 | static void __intel_power_well_put(struct drm_device *dev, | 5389 | static void hsw_power_well_enable(struct drm_i915_private *dev_priv, |
5390 | struct i915_power_well *power_well) | ||
5391 | { | ||
5392 | hsw_disable_package_c8(dev_priv); | ||
5393 | hsw_set_power_well(dev_priv, power_well, true); | ||
5394 | } | ||
5395 | |||
5396 | static void hsw_power_well_disable(struct drm_i915_private *dev_priv, | ||
5323 | struct i915_power_well *power_well) | 5397 | struct i915_power_well *power_well) |
5324 | { | 5398 | { |
5325 | struct drm_i915_private *dev_priv = dev->dev_private; | 5399 | hsw_set_power_well(dev_priv, power_well, false); |
5400 | hsw_enable_package_c8(dev_priv); | ||
5401 | } | ||
5326 | 5402 | ||
5327 | WARN_ON(!power_well->count); | 5403 | static void i9xx_always_on_power_well_noop(struct drm_i915_private *dev_priv, |
5404 | struct i915_power_well *power_well) | ||
5405 | { | ||
5406 | } | ||
5328 | 5407 | ||
5329 | if (!--power_well->count && power_well->set && | 5408 | static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv, |
5330 | i915.disable_power_well) { | 5409 | struct i915_power_well *power_well) |
5331 | power_well->set(dev, power_well, false); | 5410 | { |
5332 | hsw_enable_package_c8(dev_priv); | 5411 | return true; |
5412 | } | ||
5413 | |||
5414 | static void vlv_set_power_well(struct drm_i915_private *dev_priv, | ||
5415 | struct i915_power_well *power_well, bool enable) | ||
5416 | { | ||
5417 | enum punit_power_well power_well_id = power_well->data; | ||
5418 | u32 mask; | ||
5419 | u32 state; | ||
5420 | u32 ctrl; | ||
5421 | |||
5422 | mask = PUNIT_PWRGT_MASK(power_well_id); | ||
5423 | state = enable ? PUNIT_PWRGT_PWR_ON(power_well_id) : | ||
5424 | PUNIT_PWRGT_PWR_GATE(power_well_id); | ||
5425 | |||
5426 | mutex_lock(&dev_priv->rps.hw_lock); | ||
5427 | |||
5428 | #define COND \ | ||
5429 | ((vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask) == state) | ||
5430 | |||
5431 | if (COND) | ||
5432 | goto out; | ||
5433 | |||
5434 | ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL); | ||
5435 | ctrl &= ~mask; | ||
5436 | ctrl |= state; | ||
5437 | vlv_punit_write(dev_priv, PUNIT_REG_PWRGT_CTRL, ctrl); | ||
5438 | |||
5439 | if (wait_for(COND, 100)) | ||
5440 | DRM_ERROR("timout setting power well state %08x (%08x)\n", | ||
5441 | state, | ||
5442 | vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL)); | ||
5443 | |||
5444 | #undef COND | ||
5445 | |||
5446 | out: | ||
5447 | mutex_unlock(&dev_priv->rps.hw_lock); | ||
5448 | } | ||
5449 | |||
5450 | static void vlv_power_well_sync_hw(struct drm_i915_private *dev_priv, | ||
5451 | struct i915_power_well *power_well) | ||
5452 | { | ||
5453 | vlv_set_power_well(dev_priv, power_well, power_well->count > 0); | ||
5454 | } | ||
5455 | |||
5456 | static void vlv_power_well_enable(struct drm_i915_private *dev_priv, | ||
5457 | struct i915_power_well *power_well) | ||
5458 | { | ||
5459 | vlv_set_power_well(dev_priv, power_well, true); | ||
5460 | } | ||
5461 | |||
5462 | static void vlv_power_well_disable(struct drm_i915_private *dev_priv, | ||
5463 | struct i915_power_well *power_well) | ||
5464 | { | ||
5465 | vlv_set_power_well(dev_priv, power_well, false); | ||
5466 | } | ||
5467 | |||
5468 | static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv, | ||
5469 | struct i915_power_well *power_well) | ||
5470 | { | ||
5471 | int power_well_id = power_well->data; | ||
5472 | bool enabled = false; | ||
5473 | u32 mask; | ||
5474 | u32 state; | ||
5475 | u32 ctrl; | ||
5476 | |||
5477 | mask = PUNIT_PWRGT_MASK(power_well_id); | ||
5478 | ctrl = PUNIT_PWRGT_PWR_ON(power_well_id); | ||
5479 | |||
5480 | mutex_lock(&dev_priv->rps.hw_lock); | ||
5481 | |||
5482 | state = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask; | ||
5483 | /* | ||
5484 | * We only ever set the power-on and power-gate states, anything | ||
5485 | * else is unexpected. | ||
5486 | */ | ||
5487 | WARN_ON(state != PUNIT_PWRGT_PWR_ON(power_well_id) && | ||
5488 | state != PUNIT_PWRGT_PWR_GATE(power_well_id)); | ||
5489 | if (state == ctrl) | ||
5490 | enabled = true; | ||
5491 | |||
5492 | /* | ||
5493 | * A transient state at this point would mean some unexpected party | ||
5494 | * is poking at the power controls too. | ||
5495 | */ | ||
5496 | ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL) & mask; | ||
5497 | WARN_ON(ctrl != state); | ||
5498 | |||
5499 | mutex_unlock(&dev_priv->rps.hw_lock); | ||
5500 | |||
5501 | return enabled; | ||
5502 | } | ||
5503 | |||
5504 | static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv, | ||
5505 | struct i915_power_well *power_well) | ||
5506 | { | ||
5507 | WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D); | ||
5508 | |||
5509 | vlv_set_power_well(dev_priv, power_well, true); | ||
5510 | |||
5511 | spin_lock_irq(&dev_priv->irq_lock); | ||
5512 | valleyview_enable_display_irqs(dev_priv); | ||
5513 | spin_unlock_irq(&dev_priv->irq_lock); | ||
5514 | |||
5515 | /* | ||
5516 | * During driver initialization we need to defer enabling hotplug | ||
5517 | * processing until fbdev is set up. | ||
5518 | */ | ||
5519 | if (dev_priv->enable_hotplug_processing) | ||
5520 | intel_hpd_init(dev_priv->dev); | ||
5521 | |||
5522 | i915_redisable_vga_power_on(dev_priv->dev); | ||
5523 | } | ||
5524 | |||
5525 | static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv, | ||
5526 | struct i915_power_well *power_well) | ||
5527 | { | ||
5528 | struct drm_device *dev = dev_priv->dev; | ||
5529 | enum pipe pipe; | ||
5530 | |||
5531 | WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D); | ||
5532 | |||
5533 | spin_lock_irq(&dev_priv->irq_lock); | ||
5534 | for_each_pipe(pipe) | ||
5535 | __intel_set_cpu_fifo_underrun_reporting(dev, pipe, false); | ||
5536 | |||
5537 | valleyview_disable_display_irqs(dev_priv); | ||
5538 | spin_unlock_irq(&dev_priv->irq_lock); | ||
5539 | |||
5540 | spin_lock_irq(&dev->vbl_lock); | ||
5541 | for_each_pipe(pipe) | ||
5542 | reset_vblank_counter(dev, pipe); | ||
5543 | spin_unlock_irq(&dev->vbl_lock); | ||
5544 | |||
5545 | vlv_set_power_well(dev_priv, power_well, false); | ||
5546 | } | ||
5547 | |||
5548 | static void check_power_well_state(struct drm_i915_private *dev_priv, | ||
5549 | struct i915_power_well *power_well) | ||
5550 | { | ||
5551 | bool enabled = power_well->ops->is_enabled(dev_priv, power_well); | ||
5552 | |||
5553 | if (power_well->always_on || !i915.disable_power_well) { | ||
5554 | if (!enabled) | ||
5555 | goto mismatch; | ||
5556 | |||
5557 | return; | ||
5333 | } | 5558 | } |
5559 | |||
5560 | if (enabled != (power_well->count > 0)) | ||
5561 | goto mismatch; | ||
5562 | |||
5563 | return; | ||
5564 | |||
5565 | mismatch: | ||
5566 | WARN(1, "state mismatch for '%s' (always_on %d hw state %d use-count %d disable_power_well %d\n", | ||
5567 | power_well->name, power_well->always_on, enabled, | ||
5568 | power_well->count, i915.disable_power_well); | ||
5334 | } | 5569 | } |
5335 | 5570 | ||
5336 | void intel_display_power_get(struct drm_device *dev, | 5571 | void intel_display_power_get(struct drm_i915_private *dev_priv, |
5337 | enum intel_display_power_domain domain) | 5572 | enum intel_display_power_domain domain) |
5338 | { | 5573 | { |
5339 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5340 | struct i915_power_domains *power_domains; | 5574 | struct i915_power_domains *power_domains; |
5341 | struct i915_power_well *power_well; | 5575 | struct i915_power_well *power_well; |
5342 | int i; | 5576 | int i; |
@@ -5345,18 +5579,23 @@ void intel_display_power_get(struct drm_device *dev, | |||
5345 | 5579 | ||
5346 | mutex_lock(&power_domains->lock); | 5580 | mutex_lock(&power_domains->lock); |
5347 | 5581 | ||
5348 | for_each_power_well(i, power_well, BIT(domain), power_domains) | 5582 | for_each_power_well(i, power_well, BIT(domain), power_domains) { |
5349 | __intel_power_well_get(dev, power_well); | 5583 | if (!power_well->count++) { |
5584 | DRM_DEBUG_KMS("enabling %s\n", power_well->name); | ||
5585 | power_well->ops->enable(dev_priv, power_well); | ||
5586 | } | ||
5587 | |||
5588 | check_power_well_state(dev_priv, power_well); | ||
5589 | } | ||
5350 | 5590 | ||
5351 | power_domains->domain_use_count[domain]++; | 5591 | power_domains->domain_use_count[domain]++; |
5352 | 5592 | ||
5353 | mutex_unlock(&power_domains->lock); | 5593 | mutex_unlock(&power_domains->lock); |
5354 | } | 5594 | } |
5355 | 5595 | ||
5356 | void intel_display_power_put(struct drm_device *dev, | 5596 | void intel_display_power_put(struct drm_i915_private *dev_priv, |
5357 | enum intel_display_power_domain domain) | 5597 | enum intel_display_power_domain domain) |
5358 | { | 5598 | { |
5359 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5360 | struct i915_power_domains *power_domains; | 5599 | struct i915_power_domains *power_domains; |
5361 | struct i915_power_well *power_well; | 5600 | struct i915_power_well *power_well; |
5362 | int i; | 5601 | int i; |
@@ -5368,8 +5607,16 @@ void intel_display_power_put(struct drm_device *dev, | |||
5368 | WARN_ON(!power_domains->domain_use_count[domain]); | 5607 | WARN_ON(!power_domains->domain_use_count[domain]); |
5369 | power_domains->domain_use_count[domain]--; | 5608 | power_domains->domain_use_count[domain]--; |
5370 | 5609 | ||
5371 | for_each_power_well_rev(i, power_well, BIT(domain), power_domains) | 5610 | for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { |
5372 | __intel_power_well_put(dev, power_well); | 5611 | WARN_ON(!power_well->count); |
5612 | |||
5613 | if (!--power_well->count && i915.disable_power_well) { | ||
5614 | DRM_DEBUG_KMS("disabling %s\n", power_well->name); | ||
5615 | power_well->ops->disable(dev_priv, power_well); | ||
5616 | } | ||
5617 | |||
5618 | check_power_well_state(dev_priv, power_well); | ||
5619 | } | ||
5373 | 5620 | ||
5374 | mutex_unlock(&power_domains->lock); | 5621 | mutex_unlock(&power_domains->lock); |
5375 | } | 5622 | } |
@@ -5386,7 +5633,7 @@ void i915_request_power_well(void) | |||
5386 | 5633 | ||
5387 | dev_priv = container_of(hsw_pwr, struct drm_i915_private, | 5634 | dev_priv = container_of(hsw_pwr, struct drm_i915_private, |
5388 | power_domains); | 5635 | power_domains); |
5389 | intel_display_power_get(dev_priv->dev, POWER_DOMAIN_AUDIO); | 5636 | intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO); |
5390 | } | 5637 | } |
5391 | EXPORT_SYMBOL_GPL(i915_request_power_well); | 5638 | EXPORT_SYMBOL_GPL(i915_request_power_well); |
5392 | 5639 | ||
@@ -5400,29 +5647,99 @@ void i915_release_power_well(void) | |||
5400 | 5647 | ||
5401 | dev_priv = container_of(hsw_pwr, struct drm_i915_private, | 5648 | dev_priv = container_of(hsw_pwr, struct drm_i915_private, |
5402 | power_domains); | 5649 | power_domains); |
5403 | intel_display_power_put(dev_priv->dev, POWER_DOMAIN_AUDIO); | 5650 | intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO); |
5404 | } | 5651 | } |
5405 | EXPORT_SYMBOL_GPL(i915_release_power_well); | 5652 | EXPORT_SYMBOL_GPL(i915_release_power_well); |
5406 | 5653 | ||
5654 | #define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1) | ||
5655 | |||
5656 | #define HSW_ALWAYS_ON_POWER_DOMAINS ( \ | ||
5657 | BIT(POWER_DOMAIN_PIPE_A) | \ | ||
5658 | BIT(POWER_DOMAIN_TRANSCODER_EDP) | \ | ||
5659 | BIT(POWER_DOMAIN_PORT_DDI_A_2_LANES) | \ | ||
5660 | BIT(POWER_DOMAIN_PORT_DDI_A_4_LANES) | \ | ||
5661 | BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \ | ||
5662 | BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \ | ||
5663 | BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \ | ||
5664 | BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ | ||
5665 | BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) | \ | ||
5666 | BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \ | ||
5667 | BIT(POWER_DOMAIN_PORT_CRT) | \ | ||
5668 | BIT(POWER_DOMAIN_INIT)) | ||
5669 | #define HSW_DISPLAY_POWER_DOMAINS ( \ | ||
5670 | (POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS) | \ | ||
5671 | BIT(POWER_DOMAIN_INIT)) | ||
5672 | |||
5673 | #define BDW_ALWAYS_ON_POWER_DOMAINS ( \ | ||
5674 | HSW_ALWAYS_ON_POWER_DOMAINS | \ | ||
5675 | BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER)) | ||
5676 | #define BDW_DISPLAY_POWER_DOMAINS ( \ | ||
5677 | (POWER_DOMAIN_MASK & ~BDW_ALWAYS_ON_POWER_DOMAINS) | \ | ||
5678 | BIT(POWER_DOMAIN_INIT)) | ||
5679 | |||
5680 | #define VLV_ALWAYS_ON_POWER_DOMAINS BIT(POWER_DOMAIN_INIT) | ||
5681 | #define VLV_DISPLAY_POWER_DOMAINS POWER_DOMAIN_MASK | ||
5682 | |||
5683 | #define VLV_DPIO_CMN_BC_POWER_DOMAINS ( \ | ||
5684 | BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \ | ||
5685 | BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \ | ||
5686 | BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \ | ||
5687 | BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ | ||
5688 | BIT(POWER_DOMAIN_PORT_CRT) | \ | ||
5689 | BIT(POWER_DOMAIN_INIT)) | ||
5690 | |||
5691 | #define VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS ( \ | ||
5692 | BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \ | ||
5693 | BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \ | ||
5694 | BIT(POWER_DOMAIN_INIT)) | ||
5695 | |||
5696 | #define VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS ( \ | ||
5697 | BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \ | ||
5698 | BIT(POWER_DOMAIN_INIT)) | ||
5699 | |||
5700 | #define VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS ( \ | ||
5701 | BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \ | ||
5702 | BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ | ||
5703 | BIT(POWER_DOMAIN_INIT)) | ||
5704 | |||
5705 | #define VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS ( \ | ||
5706 | BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ | ||
5707 | BIT(POWER_DOMAIN_INIT)) | ||
5708 | |||
5709 | static const struct i915_power_well_ops i9xx_always_on_power_well_ops = { | ||
5710 | .sync_hw = i9xx_always_on_power_well_noop, | ||
5711 | .enable = i9xx_always_on_power_well_noop, | ||
5712 | .disable = i9xx_always_on_power_well_noop, | ||
5713 | .is_enabled = i9xx_always_on_power_well_enabled, | ||
5714 | }; | ||
5715 | |||
5407 | static struct i915_power_well i9xx_always_on_power_well[] = { | 5716 | static struct i915_power_well i9xx_always_on_power_well[] = { |
5408 | { | 5717 | { |
5409 | .name = "always-on", | 5718 | .name = "always-on", |
5410 | .always_on = 1, | 5719 | .always_on = 1, |
5411 | .domains = POWER_DOMAIN_MASK, | 5720 | .domains = POWER_DOMAIN_MASK, |
5721 | .ops = &i9xx_always_on_power_well_ops, | ||
5412 | }, | 5722 | }, |
5413 | }; | 5723 | }; |
5414 | 5724 | ||
5725 | static const struct i915_power_well_ops hsw_power_well_ops = { | ||
5726 | .sync_hw = hsw_power_well_sync_hw, | ||
5727 | .enable = hsw_power_well_enable, | ||
5728 | .disable = hsw_power_well_disable, | ||
5729 | .is_enabled = hsw_power_well_enabled, | ||
5730 | }; | ||
5731 | |||
5415 | static struct i915_power_well hsw_power_wells[] = { | 5732 | static struct i915_power_well hsw_power_wells[] = { |
5416 | { | 5733 | { |
5417 | .name = "always-on", | 5734 | .name = "always-on", |
5418 | .always_on = 1, | 5735 | .always_on = 1, |
5419 | .domains = HSW_ALWAYS_ON_POWER_DOMAINS, | 5736 | .domains = HSW_ALWAYS_ON_POWER_DOMAINS, |
5737 | .ops = &i9xx_always_on_power_well_ops, | ||
5420 | }, | 5738 | }, |
5421 | { | 5739 | { |
5422 | .name = "display", | 5740 | .name = "display", |
5423 | .domains = POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS, | 5741 | .domains = HSW_DISPLAY_POWER_DOMAINS, |
5424 | .is_enabled = hsw_power_well_enabled, | 5742 | .ops = &hsw_power_well_ops, |
5425 | .set = hsw_set_power_well, | ||
5426 | }, | 5743 | }, |
5427 | }; | 5744 | }; |
5428 | 5745 | ||
@@ -5431,12 +5748,83 @@ static struct i915_power_well bdw_power_wells[] = { | |||
5431 | .name = "always-on", | 5748 | .name = "always-on", |
5432 | .always_on = 1, | 5749 | .always_on = 1, |
5433 | .domains = BDW_ALWAYS_ON_POWER_DOMAINS, | 5750 | .domains = BDW_ALWAYS_ON_POWER_DOMAINS, |
5751 | .ops = &i9xx_always_on_power_well_ops, | ||
5434 | }, | 5752 | }, |
5435 | { | 5753 | { |
5436 | .name = "display", | 5754 | .name = "display", |
5437 | .domains = POWER_DOMAIN_MASK & ~BDW_ALWAYS_ON_POWER_DOMAINS, | 5755 | .domains = BDW_DISPLAY_POWER_DOMAINS, |
5438 | .is_enabled = hsw_power_well_enabled, | 5756 | .ops = &hsw_power_well_ops, |
5439 | .set = hsw_set_power_well, | 5757 | }, |
5758 | }; | ||
5759 | |||
5760 | static const struct i915_power_well_ops vlv_display_power_well_ops = { | ||
5761 | .sync_hw = vlv_power_well_sync_hw, | ||
5762 | .enable = vlv_display_power_well_enable, | ||
5763 | .disable = vlv_display_power_well_disable, | ||
5764 | .is_enabled = vlv_power_well_enabled, | ||
5765 | }; | ||
5766 | |||
5767 | static const struct i915_power_well_ops vlv_dpio_power_well_ops = { | ||
5768 | .sync_hw = vlv_power_well_sync_hw, | ||
5769 | .enable = vlv_power_well_enable, | ||
5770 | .disable = vlv_power_well_disable, | ||
5771 | .is_enabled = vlv_power_well_enabled, | ||
5772 | }; | ||
5773 | |||
5774 | static struct i915_power_well vlv_power_wells[] = { | ||
5775 | { | ||
5776 | .name = "always-on", | ||
5777 | .always_on = 1, | ||
5778 | .domains = VLV_ALWAYS_ON_POWER_DOMAINS, | ||
5779 | .ops = &i9xx_always_on_power_well_ops, | ||
5780 | }, | ||
5781 | { | ||
5782 | .name = "display", | ||
5783 | .domains = VLV_DISPLAY_POWER_DOMAINS, | ||
5784 | .data = PUNIT_POWER_WELL_DISP2D, | ||
5785 | .ops = &vlv_display_power_well_ops, | ||
5786 | }, | ||
5787 | { | ||
5788 | .name = "dpio-common", | ||
5789 | .domains = VLV_DPIO_CMN_BC_POWER_DOMAINS, | ||
5790 | .data = PUNIT_POWER_WELL_DPIO_CMN_BC, | ||
5791 | .ops = &vlv_dpio_power_well_ops, | ||
5792 | }, | ||
5793 | { | ||
5794 | .name = "dpio-tx-b-01", | ||
5795 | .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | | ||
5796 | VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS | | ||
5797 | VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | | ||
5798 | VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, | ||
5799 | .ops = &vlv_dpio_power_well_ops, | ||
5800 | .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_01, | ||
5801 | }, | ||
5802 | { | ||
5803 | .name = "dpio-tx-b-23", | ||
5804 | .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | | ||
5805 | VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS | | ||
5806 | VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | | ||
5807 | VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, | ||
5808 | .ops = &vlv_dpio_power_well_ops, | ||
5809 | .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_23, | ||
5810 | }, | ||
5811 | { | ||
5812 | .name = "dpio-tx-c-01", | ||
5813 | .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | | ||
5814 | VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS | | ||
5815 | VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | | ||
5816 | VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, | ||
5817 | .ops = &vlv_dpio_power_well_ops, | ||
5818 | .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_01, | ||
5819 | }, | ||
5820 | { | ||
5821 | .name = "dpio-tx-c-23", | ||
5822 | .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | | ||
5823 | VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS | | ||
5824 | VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | | ||
5825 | VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, | ||
5826 | .ops = &vlv_dpio_power_well_ops, | ||
5827 | .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_23, | ||
5440 | }, | 5828 | }, |
5441 | }; | 5829 | }; |
5442 | 5830 | ||
@@ -5445,9 +5833,8 @@ static struct i915_power_well bdw_power_wells[] = { | |||
5445 | (power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \ | 5833 | (power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \ |
5446 | }) | 5834 | }) |
5447 | 5835 | ||
5448 | int intel_power_domains_init(struct drm_device *dev) | 5836 | int intel_power_domains_init(struct drm_i915_private *dev_priv) |
5449 | { | 5837 | { |
5450 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5451 | struct i915_power_domains *power_domains = &dev_priv->power_domains; | 5838 | struct i915_power_domains *power_domains = &dev_priv->power_domains; |
5452 | 5839 | ||
5453 | mutex_init(&power_domains->lock); | 5840 | mutex_init(&power_domains->lock); |
@@ -5456,12 +5843,14 @@ int intel_power_domains_init(struct drm_device *dev) | |||
5456 | * The enabling order will be from lower to higher indexed wells, | 5843 | * The enabling order will be from lower to higher indexed wells, |
5457 | * the disabling order is reversed. | 5844 | * the disabling order is reversed. |
5458 | */ | 5845 | */ |
5459 | if (IS_HASWELL(dev)) { | 5846 | if (IS_HASWELL(dev_priv->dev)) { |
5460 | set_power_wells(power_domains, hsw_power_wells); | 5847 | set_power_wells(power_domains, hsw_power_wells); |
5461 | hsw_pwr = power_domains; | 5848 | hsw_pwr = power_domains; |
5462 | } else if (IS_BROADWELL(dev)) { | 5849 | } else if (IS_BROADWELL(dev_priv->dev)) { |
5463 | set_power_wells(power_domains, bdw_power_wells); | 5850 | set_power_wells(power_domains, bdw_power_wells); |
5464 | hsw_pwr = power_domains; | 5851 | hsw_pwr = power_domains; |
5852 | } else if (IS_VALLEYVIEW(dev_priv->dev)) { | ||
5853 | set_power_wells(power_domains, vlv_power_wells); | ||
5465 | } else { | 5854 | } else { |
5466 | set_power_wells(power_domains, i9xx_always_on_power_well); | 5855 | set_power_wells(power_domains, i9xx_always_on_power_well); |
5467 | } | 5856 | } |
@@ -5469,47 +5858,28 @@ int intel_power_domains_init(struct drm_device *dev) | |||
5469 | return 0; | 5858 | return 0; |
5470 | } | 5859 | } |
5471 | 5860 | ||
5472 | void intel_power_domains_remove(struct drm_device *dev) | 5861 | void intel_power_domains_remove(struct drm_i915_private *dev_priv) |
5473 | { | 5862 | { |
5474 | hsw_pwr = NULL; | 5863 | hsw_pwr = NULL; |
5475 | } | 5864 | } |
5476 | 5865 | ||
5477 | static void intel_power_domains_resume(struct drm_device *dev) | 5866 | static void intel_power_domains_resume(struct drm_i915_private *dev_priv) |
5478 | { | 5867 | { |
5479 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5480 | struct i915_power_domains *power_domains = &dev_priv->power_domains; | 5868 | struct i915_power_domains *power_domains = &dev_priv->power_domains; |
5481 | struct i915_power_well *power_well; | 5869 | struct i915_power_well *power_well; |
5482 | int i; | 5870 | int i; |
5483 | 5871 | ||
5484 | mutex_lock(&power_domains->lock); | 5872 | mutex_lock(&power_domains->lock); |
5485 | for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) { | 5873 | for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) |
5486 | if (power_well->set) | 5874 | power_well->ops->sync_hw(dev_priv, power_well); |
5487 | power_well->set(dev, power_well, power_well->count > 0); | ||
5488 | } | ||
5489 | mutex_unlock(&power_domains->lock); | 5875 | mutex_unlock(&power_domains->lock); |
5490 | } | 5876 | } |
5491 | 5877 | ||
5492 | /* | 5878 | void intel_power_domains_init_hw(struct drm_i915_private *dev_priv) |
5493 | * Starting with Haswell, we have a "Power Down Well" that can be turned off | ||
5494 | * when not needed anymore. We have 4 registers that can request the power well | ||
5495 | * to be enabled, and it will only be disabled if none of the registers is | ||
5496 | * requesting it to be enabled. | ||
5497 | */ | ||
5498 | void intel_power_domains_init_hw(struct drm_device *dev) | ||
5499 | { | 5879 | { |
5500 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5501 | |||
5502 | /* For now, we need the power well to be always enabled. */ | 5880 | /* For now, we need the power well to be always enabled. */ |
5503 | intel_display_set_init_power(dev, true); | 5881 | intel_display_set_init_power(dev_priv, true); |
5504 | intel_power_domains_resume(dev); | 5882 | intel_power_domains_resume(dev_priv); |
5505 | |||
5506 | if (!(IS_HASWELL(dev) || IS_BROADWELL(dev))) | ||
5507 | return; | ||
5508 | |||
5509 | /* We're taking over the BIOS, so clear any requests made by it since | ||
5510 | * the driver is in charge now. */ | ||
5511 | if (I915_READ(HSW_PWR_WELL_BIOS) & HSW_PWR_WELL_ENABLE_REQUEST) | ||
5512 | I915_WRITE(HSW_PWR_WELL_BIOS, 0); | ||
5513 | } | 5883 | } |
5514 | 5884 | ||
5515 | /* Disables PC8 so we can use the GMBUS and DP AUX interrupts. */ | 5885 | /* Disables PC8 so we can use the GMBUS and DP AUX interrupts. */ |
@@ -5786,10 +6156,9 @@ void intel_pm_setup(struct drm_device *dev) | |||
5786 | 6156 | ||
5787 | mutex_init(&dev_priv->pc8.lock); | 6157 | mutex_init(&dev_priv->pc8.lock); |
5788 | dev_priv->pc8.requirements_met = false; | 6158 | dev_priv->pc8.requirements_met = false; |
5789 | dev_priv->pc8.gpu_idle = false; | ||
5790 | dev_priv->pc8.irqs_disabled = false; | 6159 | dev_priv->pc8.irqs_disabled = false; |
5791 | dev_priv->pc8.enabled = false; | 6160 | dev_priv->pc8.enabled = false; |
5792 | dev_priv->pc8.disable_count = 2; /* requirements_met + gpu_idle */ | 6161 | dev_priv->pc8.disable_count = 1; /* requirements_met */ |
5793 | INIT_DELAYED_WORK(&dev_priv->pc8.enable_work, hsw_enable_pc8_work); | 6162 | INIT_DELAYED_WORK(&dev_priv->pc8.enable_work, hsw_enable_pc8_work); |
5794 | INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work, | 6163 | INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work, |
5795 | intel_gen6_powersave_work); | 6164 | intel_gen6_powersave_work); |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index b340c7587629..859092130c18 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -571,7 +571,7 @@ static int init_render_ring(struct intel_ring_buffer *ring) | |||
571 | * to use MI_WAIT_FOR_EVENT within the CS. It should already be | 571 | * to use MI_WAIT_FOR_EVENT within the CS. It should already be |
572 | * programmed to '1' on all products. | 572 | * programmed to '1' on all products. |
573 | * | 573 | * |
574 | * WaDisableAsyncFlipPerfMode:snb,ivb,hsw,vlv | 574 | * WaDisableAsyncFlipPerfMode:snb,ivb,hsw,vlv,bdw |
575 | */ | 575 | */ |
576 | if (INTEL_INFO(dev)->gen >= 6) | 576 | if (INTEL_INFO(dev)->gen >= 6) |
577 | I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(ASYNC_FLIP_PERF_DISABLE)); | 577 | I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(ASYNC_FLIP_PERF_DISABLE)); |
@@ -1388,6 +1388,8 @@ static int intel_init_ring_buffer(struct drm_device *dev, | |||
1388 | if (IS_I830(ring->dev) || IS_845G(ring->dev)) | 1388 | if (IS_I830(ring->dev) || IS_845G(ring->dev)) |
1389 | ring->effective_size -= 128; | 1389 | ring->effective_size -= 128; |
1390 | 1390 | ||
1391 | i915_cmd_parser_init_ring(ring); | ||
1392 | |||
1391 | return 0; | 1393 | return 0; |
1392 | 1394 | ||
1393 | err_unmap: | 1395 | err_unmap: |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 08b91c6ac70a..09af92099c1b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -164,6 +164,38 @@ struct intel_ring_buffer { | |||
164 | u32 gtt_offset; | 164 | u32 gtt_offset; |
165 | volatile u32 *cpu_page; | 165 | volatile u32 *cpu_page; |
166 | } scratch; | 166 | } scratch; |
167 | |||
168 | /* | ||
169 | * Tables of commands the command parser needs to know about | ||
170 | * for this ring. | ||
171 | */ | ||
172 | const struct drm_i915_cmd_table *cmd_tables; | ||
173 | int cmd_table_count; | ||
174 | |||
175 | /* | ||
176 | * Table of registers allowed in commands that read/write registers. | ||
177 | */ | ||
178 | const u32 *reg_table; | ||
179 | int reg_count; | ||
180 | |||
181 | /* | ||
182 | * Table of registers allowed in commands that read/write registers, but | ||
183 | * only from the DRM master. | ||
184 | */ | ||
185 | const u32 *master_reg_table; | ||
186 | int master_reg_count; | ||
187 | |||
188 | /* | ||
189 | * Returns the bitmask for the length field of the specified command. | ||
190 | * Return 0 for an unrecognized/invalid command. | ||
191 | * | ||
192 | * If the command parser finds an entry for a command in the ring's | ||
193 | * cmd_tables, it gets the command's length based on the table entry. | ||
194 | * If not, it calls this function to determine the per-ring length field | ||
195 | * encoding for the command (i.e. certain opcode ranges use certain bits | ||
196 | * to encode the command length in the header). | ||
197 | */ | ||
198 | u32 (*get_cmd_length_mask)(u32 cmd_header); | ||
167 | }; | 199 | }; |
168 | 200 | ||
169 | static inline bool | 201 | static inline bool |
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index c62841404c82..7861d97600e1 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c | |||
@@ -40,6 +40,12 @@ | |||
40 | 40 | ||
41 | #define __raw_posting_read(dev_priv__, reg__) (void)__raw_i915_read32(dev_priv__, reg__) | 41 | #define __raw_posting_read(dev_priv__, reg__) (void)__raw_i915_read32(dev_priv__, reg__) |
42 | 42 | ||
43 | static void | ||
44 | assert_device_not_suspended(struct drm_i915_private *dev_priv) | ||
45 | { | ||
46 | WARN(HAS_RUNTIME_PM(dev_priv->dev) && dev_priv->pm.suspended, | ||
47 | "Device suspended\n"); | ||
48 | } | ||
43 | 49 | ||
44 | static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv) | 50 | static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv) |
45 | { | 51 | { |
@@ -83,14 +89,14 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, | |||
83 | __gen6_gt_wait_for_thread_c0(dev_priv); | 89 | __gen6_gt_wait_for_thread_c0(dev_priv); |
84 | } | 90 | } |
85 | 91 | ||
86 | static void __gen6_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv) | 92 | static void __gen7_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv) |
87 | { | 93 | { |
88 | __raw_i915_write32(dev_priv, FORCEWAKE_MT, _MASKED_BIT_DISABLE(0xffff)); | 94 | __raw_i915_write32(dev_priv, FORCEWAKE_MT, _MASKED_BIT_DISABLE(0xffff)); |
89 | /* something from same cacheline, but !FORCEWAKE_MT */ | 95 | /* something from same cacheline, but !FORCEWAKE_MT */ |
90 | __raw_posting_read(dev_priv, ECOBUS); | 96 | __raw_posting_read(dev_priv, ECOBUS); |
91 | } | 97 | } |
92 | 98 | ||
93 | static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv, | 99 | static void __gen7_gt_force_wake_mt_get(struct drm_i915_private *dev_priv, |
94 | int fw_engine) | 100 | int fw_engine) |
95 | { | 101 | { |
96 | u32 forcewake_ack; | 102 | u32 forcewake_ack; |
@@ -136,14 +142,16 @@ static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, | |||
136 | gen6_gt_check_fifodbg(dev_priv); | 142 | gen6_gt_check_fifodbg(dev_priv); |
137 | } | 143 | } |
138 | 144 | ||
139 | static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv, | 145 | static void __gen7_gt_force_wake_mt_put(struct drm_i915_private *dev_priv, |
140 | int fw_engine) | 146 | int fw_engine) |
141 | { | 147 | { |
142 | __raw_i915_write32(dev_priv, FORCEWAKE_MT, | 148 | __raw_i915_write32(dev_priv, FORCEWAKE_MT, |
143 | _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); | 149 | _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); |
144 | /* something from same cacheline, but !FORCEWAKE_MT */ | 150 | /* something from same cacheline, but !FORCEWAKE_MT */ |
145 | __raw_posting_read(dev_priv, ECOBUS); | 151 | __raw_posting_read(dev_priv, ECOBUS); |
146 | gen6_gt_check_fifodbg(dev_priv); | 152 | |
153 | if (IS_GEN7(dev_priv->dev)) | ||
154 | gen6_gt_check_fifodbg(dev_priv); | ||
147 | } | 155 | } |
148 | 156 | ||
149 | static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) | 157 | static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) |
@@ -251,16 +259,16 @@ void vlv_force_wake_get(struct drm_i915_private *dev_priv, | |||
251 | unsigned long irqflags; | 259 | unsigned long irqflags; |
252 | 260 | ||
253 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); | 261 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); |
254 | if (FORCEWAKE_RENDER & fw_engine) { | 262 | |
255 | if (dev_priv->uncore.fw_rendercount++ == 0) | 263 | if (fw_engine & FORCEWAKE_RENDER && |
256 | dev_priv->uncore.funcs.force_wake_get(dev_priv, | 264 | dev_priv->uncore.fw_rendercount++ != 0) |
257 | FORCEWAKE_RENDER); | 265 | fw_engine &= ~FORCEWAKE_RENDER; |
258 | } | 266 | if (fw_engine & FORCEWAKE_MEDIA && |
259 | if (FORCEWAKE_MEDIA & fw_engine) { | 267 | dev_priv->uncore.fw_mediacount++ != 0) |
260 | if (dev_priv->uncore.fw_mediacount++ == 0) | 268 | fw_engine &= ~FORCEWAKE_MEDIA; |
261 | dev_priv->uncore.funcs.force_wake_get(dev_priv, | 269 | |
262 | FORCEWAKE_MEDIA); | 270 | if (fw_engine) |
263 | } | 271 | dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_engine); |
264 | 272 | ||
265 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); | 273 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); |
266 | } | 274 | } |
@@ -272,46 +280,45 @@ void vlv_force_wake_put(struct drm_i915_private *dev_priv, | |||
272 | 280 | ||
273 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); | 281 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); |
274 | 282 | ||
275 | if (FORCEWAKE_RENDER & fw_engine) { | 283 | if (fw_engine & FORCEWAKE_RENDER && |
276 | WARN_ON(dev_priv->uncore.fw_rendercount == 0); | 284 | --dev_priv->uncore.fw_rendercount != 0) |
277 | if (--dev_priv->uncore.fw_rendercount == 0) | 285 | fw_engine &= ~FORCEWAKE_RENDER; |
278 | dev_priv->uncore.funcs.force_wake_put(dev_priv, | 286 | if (fw_engine & FORCEWAKE_MEDIA && |
279 | FORCEWAKE_RENDER); | 287 | --dev_priv->uncore.fw_mediacount != 0) |
280 | } | 288 | fw_engine &= ~FORCEWAKE_MEDIA; |
281 | 289 | ||
282 | if (FORCEWAKE_MEDIA & fw_engine) { | 290 | if (fw_engine) |
283 | WARN_ON(dev_priv->uncore.fw_mediacount == 0); | 291 | dev_priv->uncore.funcs.force_wake_put(dev_priv, fw_engine); |
284 | if (--dev_priv->uncore.fw_mediacount == 0) | ||
285 | dev_priv->uncore.funcs.force_wake_put(dev_priv, | ||
286 | FORCEWAKE_MEDIA); | ||
287 | } | ||
288 | 292 | ||
289 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); | 293 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); |
290 | } | 294 | } |
291 | 295 | ||
292 | static void gen6_force_wake_work(struct work_struct *work) | 296 | static void gen6_force_wake_timer(unsigned long arg) |
293 | { | 297 | { |
294 | struct drm_i915_private *dev_priv = | 298 | struct drm_i915_private *dev_priv = (void *)arg; |
295 | container_of(work, typeof(*dev_priv), uncore.force_wake_work.work); | ||
296 | unsigned long irqflags; | 299 | unsigned long irqflags; |
297 | 300 | ||
301 | assert_device_not_suspended(dev_priv); | ||
302 | |||
298 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); | 303 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); |
299 | if (--dev_priv->uncore.forcewake_count == 0) | 304 | if (--dev_priv->uncore.forcewake_count == 0) |
300 | dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL); | 305 | dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL); |
301 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); | 306 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); |
307 | |||
308 | intel_runtime_pm_put(dev_priv); | ||
302 | } | 309 | } |
303 | 310 | ||
304 | static void intel_uncore_forcewake_reset(struct drm_device *dev) | 311 | static void intel_uncore_forcewake_reset(struct drm_device *dev) |
305 | { | 312 | { |
306 | struct drm_i915_private *dev_priv = dev->dev_private; | 313 | struct drm_i915_private *dev_priv = dev->dev_private; |
307 | 314 | ||
308 | if (IS_VALLEYVIEW(dev)) { | 315 | if (IS_VALLEYVIEW(dev)) |
309 | vlv_force_wake_reset(dev_priv); | 316 | vlv_force_wake_reset(dev_priv); |
310 | } else if (INTEL_INFO(dev)->gen >= 6) { | 317 | else if (IS_GEN6(dev) || IS_GEN7(dev)) |
311 | __gen6_gt_force_wake_reset(dev_priv); | 318 | __gen6_gt_force_wake_reset(dev_priv); |
312 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) | 319 | |
313 | __gen6_gt_force_wake_mt_reset(dev_priv); | 320 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev) || IS_GEN8(dev)) |
314 | } | 321 | __gen7_gt_force_wake_mt_reset(dev_priv); |
315 | } | 322 | } |
316 | 323 | ||
317 | void intel_uncore_early_sanitize(struct drm_device *dev) | 324 | void intel_uncore_early_sanitize(struct drm_device *dev) |
@@ -354,7 +361,9 @@ void intel_uncore_sanitize(struct drm_device *dev) | |||
354 | mutex_lock(&dev_priv->rps.hw_lock); | 361 | mutex_lock(&dev_priv->rps.hw_lock); |
355 | reg_val = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS); | 362 | reg_val = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS); |
356 | 363 | ||
357 | if (reg_val & (RENDER_PWRGT | MEDIA_PWRGT | DISP2D_PWRGT)) | 364 | if (reg_val & (PUNIT_PWRGT_PWR_GATE(PUNIT_POWER_WELL_RENDER) | |
365 | PUNIT_PWRGT_PWR_GATE(PUNIT_POWER_WELL_MEDIA) | | ||
366 | PUNIT_PWRGT_PWR_GATE(PUNIT_POWER_WELL_DISP2D))) | ||
358 | vlv_punit_write(dev_priv, PUNIT_REG_PWRGT_CTRL, 0x0); | 367 | vlv_punit_write(dev_priv, PUNIT_REG_PWRGT_CTRL, 0x0); |
359 | 368 | ||
360 | mutex_unlock(&dev_priv->rps.hw_lock); | 369 | mutex_unlock(&dev_priv->rps.hw_lock); |
@@ -393,25 +402,38 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine) | |||
393 | void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine) | 402 | void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine) |
394 | { | 403 | { |
395 | unsigned long irqflags; | 404 | unsigned long irqflags; |
405 | bool delayed = false; | ||
396 | 406 | ||
397 | if (!dev_priv->uncore.funcs.force_wake_put) | 407 | if (!dev_priv->uncore.funcs.force_wake_put) |
398 | return; | 408 | return; |
399 | 409 | ||
400 | /* Redirect to VLV specific routine */ | 410 | /* Redirect to VLV specific routine */ |
401 | if (IS_VALLEYVIEW(dev_priv->dev)) | 411 | if (IS_VALLEYVIEW(dev_priv->dev)) { |
402 | return vlv_force_wake_put(dev_priv, fw_engine); | 412 | vlv_force_wake_put(dev_priv, fw_engine); |
413 | goto out; | ||
414 | } | ||
403 | 415 | ||
404 | 416 | ||
405 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); | 417 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); |
406 | if (--dev_priv->uncore.forcewake_count == 0) { | 418 | if (--dev_priv->uncore.forcewake_count == 0) { |
407 | dev_priv->uncore.forcewake_count++; | 419 | dev_priv->uncore.forcewake_count++; |
408 | mod_delayed_work(dev_priv->wq, | 420 | delayed = true; |
409 | &dev_priv->uncore.force_wake_work, | 421 | mod_timer_pinned(&dev_priv->uncore.force_wake_timer, |
410 | 1); | 422 | jiffies + 1); |
411 | } | 423 | } |
412 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); | 424 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); |
413 | 425 | ||
414 | intel_runtime_pm_put(dev_priv); | 426 | out: |
427 | if (!delayed) | ||
428 | intel_runtime_pm_put(dev_priv); | ||
429 | } | ||
430 | |||
431 | void assert_force_wake_inactive(struct drm_i915_private *dev_priv) | ||
432 | { | ||
433 | if (!dev_priv->uncore.funcs.force_wake_get) | ||
434 | return; | ||
435 | |||
436 | WARN_ON(dev_priv->uncore.forcewake_count > 0); | ||
415 | } | 437 | } |
416 | 438 | ||
417 | /* We give fast paths for the really cool registers */ | 439 | /* We give fast paths for the really cool registers */ |
@@ -446,16 +468,10 @@ hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg) | |||
446 | } | 468 | } |
447 | } | 469 | } |
448 | 470 | ||
449 | static void | ||
450 | assert_device_not_suspended(struct drm_i915_private *dev_priv) | ||
451 | { | ||
452 | WARN(HAS_RUNTIME_PM(dev_priv->dev) && dev_priv->pm.suspended, | ||
453 | "Device suspended\n"); | ||
454 | } | ||
455 | |||
456 | #define REG_READ_HEADER(x) \ | 471 | #define REG_READ_HEADER(x) \ |
457 | unsigned long irqflags; \ | 472 | unsigned long irqflags; \ |
458 | u##x val = 0; \ | 473 | u##x val = 0; \ |
474 | assert_device_not_suspended(dev_priv); \ | ||
459 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags) | 475 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags) |
460 | 476 | ||
461 | #define REG_READ_FOOTER \ | 477 | #define REG_READ_FOOTER \ |
@@ -484,17 +500,15 @@ gen5_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ | |||
484 | static u##x \ | 500 | static u##x \ |
485 | gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ | 501 | gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ |
486 | REG_READ_HEADER(x); \ | 502 | REG_READ_HEADER(x); \ |
487 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ | 503 | if (dev_priv->uncore.forcewake_count == 0 && \ |
488 | if (dev_priv->uncore.forcewake_count == 0) \ | 504 | NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ |
489 | dev_priv->uncore.funcs.force_wake_get(dev_priv, \ | 505 | dev_priv->uncore.funcs.force_wake_get(dev_priv, \ |
490 | FORCEWAKE_ALL); \ | 506 | FORCEWAKE_ALL); \ |
491 | val = __raw_i915_read##x(dev_priv, reg); \ | 507 | dev_priv->uncore.forcewake_count++; \ |
492 | if (dev_priv->uncore.forcewake_count == 0) \ | 508 | mod_timer_pinned(&dev_priv->uncore.force_wake_timer, \ |
493 | dev_priv->uncore.funcs.force_wake_put(dev_priv, \ | 509 | jiffies + 1); \ |
494 | FORCEWAKE_ALL); \ | ||
495 | } else { \ | ||
496 | val = __raw_i915_read##x(dev_priv, reg); \ | ||
497 | } \ | 510 | } \ |
511 | val = __raw_i915_read##x(dev_priv, reg); \ | ||
498 | REG_READ_FOOTER; \ | 512 | REG_READ_FOOTER; \ |
499 | } | 513 | } |
500 | 514 | ||
@@ -502,27 +516,19 @@ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ | |||
502 | static u##x \ | 516 | static u##x \ |
503 | vlv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ | 517 | vlv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ |
504 | unsigned fwengine = 0; \ | 518 | unsigned fwengine = 0; \ |
505 | unsigned *fwcount; \ | ||
506 | REG_READ_HEADER(x); \ | 519 | REG_READ_HEADER(x); \ |
507 | if (FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg)) { \ | 520 | if (FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg)) { \ |
508 | fwengine = FORCEWAKE_RENDER; \ | 521 | if (dev_priv->uncore.fw_rendercount == 0) \ |
509 | fwcount = &dev_priv->uncore.fw_rendercount; \ | 522 | fwengine = FORCEWAKE_RENDER; \ |
510 | } \ | 523 | } else if (FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(reg)) { \ |
511 | else if (FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(reg)) { \ | 524 | if (dev_priv->uncore.fw_mediacount == 0) \ |
512 | fwengine = FORCEWAKE_MEDIA; \ | 525 | fwengine = FORCEWAKE_MEDIA; \ |
513 | fwcount = &dev_priv->uncore.fw_mediacount; \ | ||
514 | } \ | 526 | } \ |
515 | if (fwengine != 0) { \ | 527 | if (fwengine) \ |
516 | if ((*fwcount)++ == 0) \ | 528 | dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \ |
517 | (dev_priv)->uncore.funcs.force_wake_get(dev_priv, \ | 529 | val = __raw_i915_read##x(dev_priv, reg); \ |
518 | fwengine); \ | 530 | if (fwengine) \ |
519 | val = __raw_i915_read##x(dev_priv, reg); \ | 531 | dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \ |
520 | if (--(*fwcount) == 0) \ | ||
521 | (dev_priv)->uncore.funcs.force_wake_put(dev_priv, \ | ||
522 | fwengine); \ | ||
523 | } else { \ | ||
524 | val = __raw_i915_read##x(dev_priv, reg); \ | ||
525 | } \ | ||
526 | REG_READ_FOOTER; \ | 532 | REG_READ_FOOTER; \ |
527 | } | 533 | } |
528 | 534 | ||
@@ -554,6 +560,7 @@ __gen4_read(64) | |||
554 | #define REG_WRITE_HEADER \ | 560 | #define REG_WRITE_HEADER \ |
555 | unsigned long irqflags; \ | 561 | unsigned long irqflags; \ |
556 | trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \ | 562 | trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \ |
563 | assert_device_not_suspended(dev_priv); \ | ||
557 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags) | 564 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags) |
558 | 565 | ||
559 | #define REG_WRITE_FOOTER \ | 566 | #define REG_WRITE_FOOTER \ |
@@ -584,7 +591,6 @@ gen6_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace | |||
584 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ | 591 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ |
585 | __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ | 592 | __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ |
586 | } \ | 593 | } \ |
587 | assert_device_not_suspended(dev_priv); \ | ||
588 | __raw_i915_write##x(dev_priv, reg, val); \ | 594 | __raw_i915_write##x(dev_priv, reg, val); \ |
589 | if (unlikely(__fifo_ret)) { \ | 595 | if (unlikely(__fifo_ret)) { \ |
590 | gen6_gt_check_fifodbg(dev_priv); \ | 596 | gen6_gt_check_fifodbg(dev_priv); \ |
@@ -600,7 +606,6 @@ hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) | |||
600 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ | 606 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ |
601 | __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ | 607 | __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ |
602 | } \ | 608 | } \ |
603 | assert_device_not_suspended(dev_priv); \ | ||
604 | hsw_unclaimed_reg_clear(dev_priv, reg); \ | 609 | hsw_unclaimed_reg_clear(dev_priv, reg); \ |
605 | __raw_i915_write##x(dev_priv, reg, val); \ | 610 | __raw_i915_write##x(dev_priv, reg, val); \ |
606 | if (unlikely(__fifo_ret)) { \ | 611 | if (unlikely(__fifo_ret)) { \ |
@@ -634,16 +639,17 @@ static bool is_gen8_shadowed(struct drm_i915_private *dev_priv, u32 reg) | |||
634 | #define __gen8_write(x) \ | 639 | #define __gen8_write(x) \ |
635 | static void \ | 640 | static void \ |
636 | gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \ | 641 | gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \ |
637 | bool __needs_put = reg < 0x40000 && !is_gen8_shadowed(dev_priv, reg); \ | ||
638 | REG_WRITE_HEADER; \ | 642 | REG_WRITE_HEADER; \ |
639 | if (__needs_put) { \ | 643 | if (reg < 0x40000 && !is_gen8_shadowed(dev_priv, reg)) { \ |
640 | dev_priv->uncore.funcs.force_wake_get(dev_priv, \ | 644 | if (dev_priv->uncore.forcewake_count == 0) \ |
641 | FORCEWAKE_ALL); \ | 645 | dev_priv->uncore.funcs.force_wake_get(dev_priv, \ |
642 | } \ | 646 | FORCEWAKE_ALL); \ |
643 | __raw_i915_write##x(dev_priv, reg, val); \ | 647 | __raw_i915_write##x(dev_priv, reg, val); \ |
644 | if (__needs_put) { \ | 648 | if (dev_priv->uncore.forcewake_count == 0) \ |
645 | dev_priv->uncore.funcs.force_wake_put(dev_priv, \ | 649 | dev_priv->uncore.funcs.force_wake_put(dev_priv, \ |
646 | FORCEWAKE_ALL); \ | 650 | FORCEWAKE_ALL); \ |
651 | } else { \ | ||
652 | __raw_i915_write##x(dev_priv, reg, val); \ | ||
647 | } \ | 653 | } \ |
648 | REG_WRITE_FOOTER; \ | 654 | REG_WRITE_FOOTER; \ |
649 | } | 655 | } |
@@ -681,15 +687,15 @@ void intel_uncore_init(struct drm_device *dev) | |||
681 | { | 687 | { |
682 | struct drm_i915_private *dev_priv = dev->dev_private; | 688 | struct drm_i915_private *dev_priv = dev->dev_private; |
683 | 689 | ||
684 | INIT_DELAYED_WORK(&dev_priv->uncore.force_wake_work, | 690 | setup_timer(&dev_priv->uncore.force_wake_timer, |
685 | gen6_force_wake_work); | 691 | gen6_force_wake_timer, (unsigned long)dev_priv); |
686 | 692 | ||
687 | if (IS_VALLEYVIEW(dev)) { | 693 | if (IS_VALLEYVIEW(dev)) { |
688 | dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get; | 694 | dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get; |
689 | dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put; | 695 | dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put; |
690 | } else if (IS_HASWELL(dev) || IS_GEN8(dev)) { | 696 | } else if (IS_HASWELL(dev) || IS_GEN8(dev)) { |
691 | dev_priv->uncore.funcs.force_wake_get = __gen6_gt_force_wake_mt_get; | 697 | dev_priv->uncore.funcs.force_wake_get = __gen7_gt_force_wake_mt_get; |
692 | dev_priv->uncore.funcs.force_wake_put = __gen6_gt_force_wake_mt_put; | 698 | dev_priv->uncore.funcs.force_wake_put = __gen7_gt_force_wake_mt_put; |
693 | } else if (IS_IVYBRIDGE(dev)) { | 699 | } else if (IS_IVYBRIDGE(dev)) { |
694 | u32 ecobus; | 700 | u32 ecobus; |
695 | 701 | ||
@@ -703,16 +709,16 @@ void intel_uncore_init(struct drm_device *dev) | |||
703 | * forcewake being disabled. | 709 | * forcewake being disabled. |
704 | */ | 710 | */ |
705 | mutex_lock(&dev->struct_mutex); | 711 | mutex_lock(&dev->struct_mutex); |
706 | __gen6_gt_force_wake_mt_get(dev_priv, FORCEWAKE_ALL); | 712 | __gen7_gt_force_wake_mt_get(dev_priv, FORCEWAKE_ALL); |
707 | ecobus = __raw_i915_read32(dev_priv, ECOBUS); | 713 | ecobus = __raw_i915_read32(dev_priv, ECOBUS); |
708 | __gen6_gt_force_wake_mt_put(dev_priv, FORCEWAKE_ALL); | 714 | __gen7_gt_force_wake_mt_put(dev_priv, FORCEWAKE_ALL); |
709 | mutex_unlock(&dev->struct_mutex); | 715 | mutex_unlock(&dev->struct_mutex); |
710 | 716 | ||
711 | if (ecobus & FORCEWAKE_MT_ENABLE) { | 717 | if (ecobus & FORCEWAKE_MT_ENABLE) { |
712 | dev_priv->uncore.funcs.force_wake_get = | 718 | dev_priv->uncore.funcs.force_wake_get = |
713 | __gen6_gt_force_wake_mt_get; | 719 | __gen7_gt_force_wake_mt_get; |
714 | dev_priv->uncore.funcs.force_wake_put = | 720 | dev_priv->uncore.funcs.force_wake_put = |
715 | __gen6_gt_force_wake_mt_put; | 721 | __gen7_gt_force_wake_mt_put; |
716 | } else { | 722 | } else { |
717 | DRM_INFO("No MT forcewake available on Ivybridge, this can result in issues\n"); | 723 | DRM_INFO("No MT forcewake available on Ivybridge, this can result in issues\n"); |
718 | DRM_INFO("when using vblank-synced partial screen updates.\n"); | 724 | DRM_INFO("when using vblank-synced partial screen updates.\n"); |
@@ -794,10 +800,11 @@ void intel_uncore_fini(struct drm_device *dev) | |||
794 | { | 800 | { |
795 | struct drm_i915_private *dev_priv = dev->dev_private; | 801 | struct drm_i915_private *dev_priv = dev->dev_private; |
796 | 802 | ||
797 | flush_delayed_work(&dev_priv->uncore.force_wake_work); | 803 | del_timer_sync(&dev_priv->uncore.force_wake_timer); |
798 | 804 | ||
799 | /* Paranoia: make sure we have disabled everything before we exit. */ | 805 | /* Paranoia: make sure we have disabled everything before we exit. */ |
800 | intel_uncore_sanitize(dev); | 806 | intel_uncore_sanitize(dev); |
807 | intel_uncore_forcewake_reset(dev); | ||
801 | } | 808 | } |
802 | 809 | ||
803 | static const struct register_whitelist { | 810 | static const struct register_whitelist { |
@@ -947,6 +954,7 @@ static int gen6_do_reset(struct drm_device *dev) | |||
947 | struct drm_i915_private *dev_priv = dev->dev_private; | 954 | struct drm_i915_private *dev_priv = dev->dev_private; |
948 | int ret; | 955 | int ret; |
949 | unsigned long irqflags; | 956 | unsigned long irqflags; |
957 | u32 fw_engine = 0; | ||
950 | 958 | ||
951 | /* Hold uncore.lock across reset to prevent any register access | 959 | /* Hold uncore.lock across reset to prevent any register access |
952 | * with forcewake not set correctly | 960 | * with forcewake not set correctly |
@@ -966,14 +974,25 @@ static int gen6_do_reset(struct drm_device *dev) | |||
966 | 974 | ||
967 | intel_uncore_forcewake_reset(dev); | 975 | intel_uncore_forcewake_reset(dev); |
968 | 976 | ||
969 | /* If reset with a user forcewake, try to restore, otherwise turn it off */ | 977 | /* If reset with a user forcewake, try to restore */ |
970 | if (dev_priv->uncore.forcewake_count) | 978 | if (IS_VALLEYVIEW(dev)) { |
971 | dev_priv->uncore.funcs.force_wake_get(dev_priv, FORCEWAKE_ALL); | 979 | if (dev_priv->uncore.fw_rendercount) |
972 | else | 980 | fw_engine |= FORCEWAKE_RENDER; |
973 | dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL); | 981 | |
982 | if (dev_priv->uncore.fw_mediacount) | ||
983 | fw_engine |= FORCEWAKE_MEDIA; | ||
984 | } else { | ||
985 | if (dev_priv->uncore.forcewake_count) | ||
986 | fw_engine = FORCEWAKE_ALL; | ||
987 | } | ||
974 | 988 | ||
975 | /* Restore fifo count */ | 989 | if (fw_engine) |
976 | dev_priv->uncore.fifo_count = __raw_i915_read32(dev_priv, GTFIFOCTL) & GT_FIFO_FREE_ENTRIES_MASK; | 990 | dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_engine); |
991 | |||
992 | if (IS_GEN6(dev) || IS_GEN7(dev)) | ||
993 | dev_priv->uncore.fifo_count = | ||
994 | __raw_i915_read32(dev_priv, GTFIFOCTL) & | ||
995 | GT_FIFO_FREE_ENTRIES_MASK; | ||
977 | 996 | ||
978 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); | 997 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); |
979 | return ret; | 998 | return ret; |