diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-15 14:19:54 +0900 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-15 14:19:54 +0900 | 
| commit | 049ffa8ab33a63b3bff672d1a0ee6a35ad253fe8 (patch) | |
| tree | 70f4c684818b1c9871fa800088427e40d260592e /drivers/gpu/host1x/syncpt.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/syncpt.c')
| -rw-r--r-- | drivers/gpu/host1x/syncpt.c | 92 | 
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 @@  #define SYNCPT_CHECK_PERIOD (2 * HZ)  #define MAX_STUCK_CHECK_COUNT 15 -static struct host1x_syncpt *_host1x_syncpt_alloc(struct host1x *host, -						  struct device *dev, -						  bool client_managed) +static struct host1x_syncpt_base * +host1x_syncpt_base_request(struct host1x *host) +{ +	struct host1x_syncpt_base *bases = host->bases; +	unsigned int i; + +	for (i = 0; i < host->info->nb_bases; i++) +		if (!bases[i].requested) +			break; + +	if (i >= host->info->nb_bases) +		return NULL; + +	bases[i].requested = true; +	return &bases[i]; +} + +static void host1x_syncpt_base_free(struct host1x_syncpt_base *base) +{ +	if (base) +		base->requested = false; +} + +static struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host, +						 struct device *dev, +						 unsigned long flags)  {  	int i;  	struct host1x_syncpt *sp = host->syncpt; @@ -44,6 +67,12 @@ static struct host1x_syncpt *_host1x_syncpt_alloc(struct host1x *host,  	if (i >= host->info->nb_pts)  		return NULL; +	if (flags & HOST1X_SYNCPT_HAS_BASE) { +		sp->base = host1x_syncpt_base_request(host); +		if (!sp->base) +			return NULL; +	} +  	name = kasprintf(GFP_KERNEL, "%02d-%s", sp->id,  			dev ? dev_name(dev) : NULL);  	if (!name) @@ -51,7 +80,11 @@ static struct host1x_syncpt *_host1x_syncpt_alloc(struct host1x *host,  	sp->dev = dev;  	sp->name = name; -	sp->client_managed = client_managed; + +	if (flags & HOST1X_SYNCPT_CLIENT_MANAGED) +		sp->client_managed = true; +	else +		sp->client_managed = false;  	return sp;  } @@ -303,25 +336,35 @@ int host1x_syncpt_patch_wait(struct host1x_syncpt *sp, void *patch_addr)  int host1x_syncpt_init(struct host1x *host)  { +	struct host1x_syncpt_base *bases;  	struct host1x_syncpt *syncpt;  	int i;  	syncpt = devm_kzalloc(host->dev, sizeof(*syncpt) * host->info->nb_pts, -		GFP_KERNEL); +			      GFP_KERNEL);  	if (!syncpt)  		return -ENOMEM; -	for (i = 0; i < host->info->nb_pts; ++i) { +	bases = devm_kzalloc(host->dev, sizeof(*bases) * host->info->nb_bases, +			     GFP_KERNEL); +	if (!bases) +		return -ENOMEM; + +	for (i = 0; i < host->info->nb_pts; i++) {  		syncpt[i].id = i;  		syncpt[i].host = host;  	} +	for (i = 0; i < host->info->nb_bases; i++) +		bases[i].id = i; +  	host->syncpt = syncpt; +	host->bases = bases;  	host1x_syncpt_restore(host);  	/* Allocate sync point to use for clearing waits for expired fences */ -	host->nop_sp = _host1x_syncpt_alloc(host, NULL, false); +	host->nop_sp = host1x_syncpt_alloc(host, NULL, 0);  	if (!host->nop_sp)  		return -ENOMEM; @@ -329,10 +372,10 @@ int host1x_syncpt_init(struct host1x *host)  }  struct host1x_syncpt *host1x_syncpt_request(struct device *dev, -					    bool client_managed) +					    unsigned long flags)  {  	struct host1x *host = dev_get_drvdata(dev->parent); -	return _host1x_syncpt_alloc(host, dev, client_managed); +	return host1x_syncpt_alloc(host, dev, flags);  }  void host1x_syncpt_free(struct host1x_syncpt *sp) @@ -340,7 +383,9 @@ void host1x_syncpt_free(struct host1x_syncpt *sp)  	if (!sp)  		return; +	host1x_syncpt_base_free(sp->base);  	kfree(sp->name); +	sp->base = NULL;  	sp->dev = NULL;  	sp->name = NULL;  	sp->client_managed = false; @@ -354,6 +399,25 @@ void host1x_syncpt_deinit(struct host1x *host)  		kfree(sp->name);  } +/* + * Read max. It indicates how many operations there are in queue, either in + * channel or in a software thread. + * */ +u32 host1x_syncpt_read_max(struct host1x_syncpt *sp) +{ +	smp_rmb(); +	return (u32)atomic_read(&sp->max_val); +} + +/* + * Read min, which is a shadow of the current sync point value in hardware. + */ +u32 host1x_syncpt_read_min(struct host1x_syncpt *sp) +{ +	smp_rmb(); +	return (u32)atomic_read(&sp->min_val); +} +  int host1x_syncpt_nb_pts(struct host1x *host)  {  	return host->info->nb_pts; @@ -375,3 +439,13 @@ struct host1x_syncpt *host1x_syncpt_get(struct host1x *host, u32 id)  		return NULL;  	return host->syncpt + id;  } + +struct host1x_syncpt_base *host1x_syncpt_get_base(struct host1x_syncpt *sp) +{ +	return sp ? sp->base : NULL; +} + +u32 host1x_syncpt_base_id(struct host1x_syncpt_base *base) +{ +	return base->id; +}  | 
