diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-15 00:19:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-15 00:19:54 -0500 |
commit | 049ffa8ab33a63b3bff672d1a0ee6a35ad253fe8 (patch) | |
tree | 70f4c684818b1c9871fa800088427e40d260592e /drivers/gpu/host1x/job.c | |
parent | c681427e5ca22925fcc1be76a2e260a11e0a8498 (diff) | |
parent | 0846c728e20a0cd1e43fb75a3015f3b176a26466 (diff) |
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie:
"This is a combo of -next and some -fixes that came in in the
intervening time.
Highlights:
New drivers:
ARM Armada driver for Marvell Armada 510 SOCs
Intel:
Broadwell initial support under a default off switch,
Stereo/3D HDMI mode support
Valleyview improvements
Displayport improvements
Haswell fixes
initial mipi dsi panel support
CRC support for debugging
build with CONFIG_FB=n
Radeon:
enable DPM on a number of GPUs by default
secondary GPU powerdown support
enable HDMI audio by default
Hawaii support
Nouveau:
dynamic pm code infrastructure reworked, does nothing major yet
GK208 modesetting support
MSI fixes, on by default again
PMPEG improvements
pageflipping fixes
GMA500:
minnowboard SDVO support
VMware:
misc fixes
MSM:
prime, plane and rendernodes support
Tegra:
rearchitected to put the drm driver into the drm subsystem.
HDMI and gr2d support for tegra 114 SoC
QXL:
oops fix, and multi-head fixes
DRM core:
sysfs lifetime fixes
client capability ioctl
further cleanups to device midlayer
more vblank timestamp fixes"
* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (789 commits)
drm/nouveau: do not map evicted vram buffers in nouveau_bo_vma_add
drm/nvc0-/gr: shift wrapping bug in nvc0_grctx_generate_r406800
drm/nouveau/pwr: fix missing mutex unlock in a failure path
drm/nv40/therm: fix slowing down fan when pstate undefined
drm/nv11-: synchronise flips to vblank, unless async flip requested
drm/nvc0-: remove nasty fifo swmthd hack for flip completion method
drm/nv10-: we no longer need to create nvsw object on user channels
drm/nouveau: always queue flips relative to kernel channel activity
drm/nouveau: there is no need to reserve/fence the new fb when flipping
drm/nouveau: when bailing out of a pushbuf ioctl, do not remove previous fence
drm/nouveau: allow nouveau_fence_ref() to be a noop
drm/nvc8/mc: msi rearm is via the nvc0 method
drm/ttm: Fix vma page_prot bit manipulation
drm/vmwgfx: Fix a couple of compile / sparse warnings and errors
drm/vmwgfx: Resource evict fixes
drm/edid: compare actual vrefresh for all modes for quirks
drm: shmob_drm: Convert to clk_prepare/unprepare
drm/nouveau: fix 32-bit build
drm/i915/opregion: fix build error on CONFIG_ACPI=n
Revert "drm/radeon/audio: don't set speaker allocation on DCE4+"
...
Diffstat (limited to 'drivers/gpu/host1x/job.c')
-rw-r--r-- | drivers/gpu/host1x/job.c | 73 |
1 files changed, 39 insertions, 34 deletions
diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c index c4e1050f2252..de5ec333ce1a 100644 --- a/drivers/gpu/host1x/job.c +++ b/drivers/gpu/host1x/job.c | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
20 | #include <linux/err.h> | 20 | #include <linux/err.h> |
21 | #include <linux/host1x.h> | ||
21 | #include <linux/kref.h> | 22 | #include <linux/kref.h> |
22 | #include <linux/module.h> | 23 | #include <linux/module.h> |
23 | #include <linux/scatterlist.h> | 24 | #include <linux/scatterlist.h> |
@@ -27,7 +28,6 @@ | |||
27 | 28 | ||
28 | #include "channel.h" | 29 | #include "channel.h" |
29 | #include "dev.h" | 30 | #include "dev.h" |
30 | #include "host1x_bo.h" | ||
31 | #include "job.h" | 31 | #include "job.h" |
32 | #include "syncpt.h" | 32 | #include "syncpt.h" |
33 | 33 | ||
@@ -264,7 +264,7 @@ static unsigned int do_relocs(struct host1x_job *job, struct host1x_bo *cmdbuf) | |||
264 | } | 264 | } |
265 | 265 | ||
266 | static bool check_reloc(struct host1x_reloc *reloc, struct host1x_bo *cmdbuf, | 266 | static bool check_reloc(struct host1x_reloc *reloc, struct host1x_bo *cmdbuf, |
267 | unsigned int offset) | 267 | unsigned int offset) |
268 | { | 268 | { |
269 | offset *= sizeof(u32); | 269 | offset *= sizeof(u32); |
270 | 270 | ||
@@ -281,7 +281,7 @@ struct host1x_firewall { | |||
281 | unsigned int num_relocs; | 281 | unsigned int num_relocs; |
282 | struct host1x_reloc *reloc; | 282 | struct host1x_reloc *reloc; |
283 | 283 | ||
284 | struct host1x_bo *cmdbuf_id; | 284 | struct host1x_bo *cmdbuf; |
285 | unsigned int offset; | 285 | unsigned int offset; |
286 | 286 | ||
287 | u32 words; | 287 | u32 words; |
@@ -291,25 +291,37 @@ struct host1x_firewall { | |||
291 | u32 count; | 291 | u32 count; |
292 | }; | 292 | }; |
293 | 293 | ||
294 | static int check_register(struct host1x_firewall *fw, unsigned long offset) | ||
295 | { | ||
296 | if (fw->job->is_addr_reg(fw->dev, fw->class, offset)) { | ||
297 | if (!fw->num_relocs) | ||
298 | return -EINVAL; | ||
299 | |||
300 | if (!check_reloc(fw->reloc, fw->cmdbuf, fw->offset)) | ||
301 | return -EINVAL; | ||
302 | |||
303 | fw->num_relocs--; | ||
304 | fw->reloc++; | ||
305 | } | ||
306 | |||
307 | return 0; | ||
308 | } | ||
309 | |||
294 | static int check_mask(struct host1x_firewall *fw) | 310 | static int check_mask(struct host1x_firewall *fw) |
295 | { | 311 | { |
296 | u32 mask = fw->mask; | 312 | u32 mask = fw->mask; |
297 | u32 reg = fw->reg; | 313 | u32 reg = fw->reg; |
314 | int ret; | ||
298 | 315 | ||
299 | while (mask) { | 316 | while (mask) { |
300 | if (fw->words == 0) | 317 | if (fw->words == 0) |
301 | return -EINVAL; | 318 | return -EINVAL; |
302 | 319 | ||
303 | if (mask & 1) { | 320 | if (mask & 1) { |
304 | if (fw->job->is_addr_reg(fw->dev, fw->class, reg)) { | 321 | ret = check_register(fw, reg); |
305 | if (!fw->num_relocs) | 322 | if (ret < 0) |
306 | return -EINVAL; | 323 | return ret; |
307 | if (!check_reloc(fw->reloc, fw->cmdbuf_id, | 324 | |
308 | fw->offset)) | ||
309 | return -EINVAL; | ||
310 | fw->reloc++; | ||
311 | fw->num_relocs--; | ||
312 | } | ||
313 | fw->words--; | 325 | fw->words--; |
314 | fw->offset++; | 326 | fw->offset++; |
315 | } | 327 | } |
@@ -324,19 +336,16 @@ static int check_incr(struct host1x_firewall *fw) | |||
324 | { | 336 | { |
325 | u32 count = fw->count; | 337 | u32 count = fw->count; |
326 | u32 reg = fw->reg; | 338 | u32 reg = fw->reg; |
339 | int ret; | ||
327 | 340 | ||
328 | while (count) { | 341 | while (count) { |
329 | if (fw->words == 0) | 342 | if (fw->words == 0) |
330 | return -EINVAL; | 343 | return -EINVAL; |
331 | 344 | ||
332 | if (fw->job->is_addr_reg(fw->dev, fw->class, reg)) { | 345 | ret = check_register(fw, reg); |
333 | if (!fw->num_relocs) | 346 | if (ret < 0) |
334 | return -EINVAL; | 347 | return ret; |
335 | if (!check_reloc(fw->reloc, fw->cmdbuf_id, fw->offset)) | 348 | |
336 | return -EINVAL; | ||
337 | fw->reloc++; | ||
338 | fw->num_relocs--; | ||
339 | } | ||
340 | reg++; | 349 | reg++; |
341 | fw->words--; | 350 | fw->words--; |
342 | fw->offset++; | 351 | fw->offset++; |
@@ -348,21 +357,17 @@ static int check_incr(struct host1x_firewall *fw) | |||
348 | 357 | ||
349 | static int check_nonincr(struct host1x_firewall *fw) | 358 | static int check_nonincr(struct host1x_firewall *fw) |
350 | { | 359 | { |
351 | int is_addr_reg = fw->job->is_addr_reg(fw->dev, fw->class, fw->reg); | ||
352 | u32 count = fw->count; | 360 | u32 count = fw->count; |
361 | int ret; | ||
353 | 362 | ||
354 | while (count) { | 363 | while (count) { |
355 | if (fw->words == 0) | 364 | if (fw->words == 0) |
356 | return -EINVAL; | 365 | return -EINVAL; |
357 | 366 | ||
358 | if (is_addr_reg) { | 367 | ret = check_register(fw, fw->reg); |
359 | if (!fw->num_relocs) | 368 | if (ret < 0) |
360 | return -EINVAL; | 369 | return ret; |
361 | if (!check_reloc(fw->reloc, fw->cmdbuf_id, fw->offset)) | 370 | |
362 | return -EINVAL; | ||
363 | fw->reloc++; | ||
364 | fw->num_relocs--; | ||
365 | } | ||
366 | fw->words--; | 371 | fw->words--; |
367 | fw->offset++; | 372 | fw->offset++; |
368 | count--; | 373 | count--; |
@@ -381,7 +386,7 @@ static int validate(struct host1x_firewall *fw, struct host1x_job_gather *g) | |||
381 | return 0; | 386 | return 0; |
382 | 387 | ||
383 | fw->words = g->words; | 388 | fw->words = g->words; |
384 | fw->cmdbuf_id = g->bo; | 389 | fw->cmdbuf = g->bo; |
385 | fw->offset = 0; | 390 | fw->offset = 0; |
386 | 391 | ||
387 | while (fw->words && !err) { | 392 | while (fw->words && !err) { |
@@ -436,10 +441,6 @@ static int validate(struct host1x_firewall *fw, struct host1x_job_gather *g) | |||
436 | } | 441 | } |
437 | } | 442 | } |
438 | 443 | ||
439 | /* No relocs should remain at this point */ | ||
440 | if (fw->num_relocs) | ||
441 | err = -EINVAL; | ||
442 | |||
443 | out: | 444 | out: |
444 | return err; | 445 | return err; |
445 | } | 446 | } |
@@ -493,6 +494,10 @@ static inline int copy_gathers(struct host1x_job *job, struct device *dev) | |||
493 | offset += g->words * sizeof(u32); | 494 | offset += g->words * sizeof(u32); |
494 | } | 495 | } |
495 | 496 | ||
497 | /* No relocs should remain at this point */ | ||
498 | if (fw.num_relocs) | ||
499 | return -EINVAL; | ||
500 | |||
496 | return 0; | 501 | return 0; |
497 | } | 502 | } |
498 | 503 | ||