aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/host1x/syncpt.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-15 00:19:54 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-15 00:19:54 -0500
commit049ffa8ab33a63b3bff672d1a0ee6a35ad253fe8 (patch)
tree70f4c684818b1c9871fa800088427e40d260592e /drivers/gpu/host1x/syncpt.c
parentc681427e5ca22925fcc1be76a2e260a11e0a8498 (diff)
parent0846c728e20a0cd1e43fb75a3015f3b176a26466 (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/syncpt.c')
-rw-r--r--drivers/gpu/host1x/syncpt.c92
1 files changed, 83 insertions, 9 deletions
diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c
index 409745b949db..159c479829c9 100644
--- a/drivers/gpu/host1x/syncpt.c
+++ b/drivers/gpu/host1x/syncpt.c
@@ -30,9 +30,32 @@
30#define SYNCPT_CHECK_PERIOD (2 * HZ) 30#define SYNCPT_CHECK_PERIOD (2 * HZ)
31#define MAX_STUCK_CHECK_COUNT 15 31#define MAX_STUCK_CHECK_COUNT 15
32 32
33static struct host1x_syncpt *_host1x_syncpt_alloc(struct host1x *host, 33static struct host1x_syncpt_base *
34 struct device *dev, 34host1x_syncpt_base_request(struct host1x *host)
35 bool client_managed) 35{
36 struct host1x_syncpt_base *bases = host->bases;
37 unsigned int i;
38
39 for (i = 0; i < host->info->nb_bases; i++)
40 if (!bases[i].requested)
41 break;
42
43 if (i >= host->info->nb_bases)
44 return NULL;
45
46 bases[i].requested = true;
47 return &bases[i];
48}
49
50static void host1x_syncpt_base_free(struct host1x_syncpt_base *base)
51{
52 if (base)
53 base->requested = false;
54}
55
56static struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
57 struct device *dev,
58 unsigned long flags)
36{ 59{
37 int i; 60 int i;
38 struct host1x_syncpt *sp = host->syncpt; 61 struct host1x_syncpt *sp = host->syncpt;
@@ -44,6 +67,12 @@ static struct host1x_syncpt *_host1x_syncpt_alloc(struct host1x *host,
44 if (i >= host->info->nb_pts) 67 if (i >= host->info->nb_pts)
45 return NULL; 68 return NULL;
46 69
70 if (flags & HOST1X_SYNCPT_HAS_BASE) {
71 sp->base = host1x_syncpt_base_request(host);
72 if (!sp->base)
73 return NULL;
74 }
75
47 name = kasprintf(GFP_KERNEL, "%02d-%s", sp->id, 76 name = kasprintf(GFP_KERNEL, "%02d-%s", sp->id,
48 dev ? dev_name(dev) : NULL); 77 dev ? dev_name(dev) : NULL);
49 if (!name) 78 if (!name)
@@ -51,7 +80,11 @@ static struct host1x_syncpt *_host1x_syncpt_alloc(struct host1x *host,
51 80
52 sp->dev = dev; 81 sp->dev = dev;
53 sp->name = name; 82 sp->name = name;
54 sp->client_managed = client_managed; 83
84 if (flags & HOST1X_SYNCPT_CLIENT_MANAGED)
85 sp->client_managed = true;
86 else
87 sp->client_managed = false;
55 88
56 return sp; 89 return sp;
57} 90}
@@ -303,25 +336,35 @@ int host1x_syncpt_patch_wait(struct host1x_syncpt *sp, void *patch_addr)
303 336
304int host1x_syncpt_init(struct host1x *host) 337int host1x_syncpt_init(struct host1x *host)
305{ 338{
339 struct host1x_syncpt_base *bases;
306 struct host1x_syncpt *syncpt; 340 struct host1x_syncpt *syncpt;
307 int i; 341 int i;
308 342
309 syncpt = devm_kzalloc(host->dev, sizeof(*syncpt) * host->info->nb_pts, 343 syncpt = devm_kzalloc(host->dev, sizeof(*syncpt) * host->info->nb_pts,
310 GFP_KERNEL); 344 GFP_KERNEL);
311 if (!syncpt) 345 if (!syncpt)
312 return -ENOMEM; 346 return -ENOMEM;
313 347
314 for (i = 0; i < host->info->nb_pts; ++i) { 348 bases = devm_kzalloc(host->dev, sizeof(*bases) * host->info->nb_bases,
349 GFP_KERNEL);
350 if (!bases)
351 return -ENOMEM;
352
353 for (i = 0; i < host->info->nb_pts; i++) {
315 syncpt[i].id = i; 354 syncpt[i].id = i;
316 syncpt[i].host = host; 355 syncpt[i].host = host;
317 } 356 }
318 357
358 for (i = 0; i < host->info->nb_bases; i++)
359 bases[i].id = i;
360
319 host->syncpt = syncpt; 361 host->syncpt = syncpt;
362 host->bases = bases;
320 363
321 host1x_syncpt_restore(host); 364 host1x_syncpt_restore(host);
322 365
323 /* Allocate sync point to use for clearing waits for expired fences */ 366 /* Allocate sync point to use for clearing waits for expired fences */
324 host->nop_sp = _host1x_syncpt_alloc(host, NULL, false); 367 host->nop_sp = host1x_syncpt_alloc(host, NULL, 0);
325 if (!host->nop_sp) 368 if (!host->nop_sp)
326 return -ENOMEM; 369 return -ENOMEM;
327 370
@@ -329,10 +372,10 @@ int host1x_syncpt_init(struct host1x *host)
329} 372}
330 373
331struct host1x_syncpt *host1x_syncpt_request(struct device *dev, 374struct host1x_syncpt *host1x_syncpt_request(struct device *dev,
332 bool client_managed) 375 unsigned long flags)
333{ 376{
334 struct host1x *host = dev_get_drvdata(dev->parent); 377 struct host1x *host = dev_get_drvdata(dev->parent);
335 return _host1x_syncpt_alloc(host, dev, client_managed); 378 return host1x_syncpt_alloc(host, dev, flags);
336} 379}
337 380
338void host1x_syncpt_free(struct host1x_syncpt *sp) 381void host1x_syncpt_free(struct host1x_syncpt *sp)
@@ -340,7 +383,9 @@ void host1x_syncpt_free(struct host1x_syncpt *sp)
340 if (!sp) 383 if (!sp)
341 return; 384 return;
342 385
386 host1x_syncpt_base_free(sp->base);
343 kfree(sp->name); 387 kfree(sp->name);
388 sp->base = NULL;
344 sp->dev = NULL; 389 sp->dev = NULL;
345 sp->name = NULL; 390 sp->name = NULL;
346 sp->client_managed = false; 391 sp->client_managed = false;
@@ -354,6 +399,25 @@ void host1x_syncpt_deinit(struct host1x *host)
354 kfree(sp->name); 399 kfree(sp->name);
355} 400}
356 401
402/*
403 * Read max. It indicates how many operations there are in queue, either in
404 * channel or in a software thread.
405 * */
406u32 host1x_syncpt_read_max(struct host1x_syncpt *sp)
407{
408 smp_rmb();
409 return (u32)atomic_read(&sp->max_val);
410}
411
412/*
413 * Read min, which is a shadow of the current sync point value in hardware.
414 */
415u32 host1x_syncpt_read_min(struct host1x_syncpt *sp)
416{
417 smp_rmb();
418 return (u32)atomic_read(&sp->min_val);
419}
420
357int host1x_syncpt_nb_pts(struct host1x *host) 421int host1x_syncpt_nb_pts(struct host1x *host)
358{ 422{
359 return host->info->nb_pts; 423 return host->info->nb_pts;
@@ -375,3 +439,13 @@ struct host1x_syncpt *host1x_syncpt_get(struct host1x *host, u32 id)
375 return NULL; 439 return NULL;
376 return host->syncpt + id; 440 return host->syncpt + id;
377} 441}
442
443struct host1x_syncpt_base *host1x_syncpt_get_base(struct host1x_syncpt *sp)
444{
445 return sp ? sp->base : NULL;
446}
447
448u32 host1x_syncpt_base_id(struct host1x_syncpt_base *base)
449{
450 return base->id;
451}