/*
 * Write cmdbuf to ftrace output. Checks if cmdbuf contents should be output
 * and mmaps the cmdbuf contents if required.
 */
static void trace_write_cmdbufs(struct nvhost_job *job)
{
	struct nvmap_handle_ref handle;
	void *mem = NULL;
	int i = 0;

	for (i = 0; i < job->num_gathers; i++) {
		struct nvhost_channel_gather *gather = &job->gathers[i];
		if (nvhost_debug_trace_cmdbuf) {
			handle.handle = nvmap_id_to_handle(gather->mem_id);
			mem = nvmap_mmap(&handle);
			if (IS_ERR_OR_NULL(mem))
				mem = NULL;
		};

		if (mem) {
			u32 i;
			/*
			 * Write in batches of 128 as there seems to be a limit
			 * of how much you can output to ftrace at once.
			 */
			for (i = 0; i < gather->words; i += TRACE_MAX_LENGTH) {
				trace_nvhost_channel_write_cmdbuf_data(
					job->ch->desc->name,
					gather->mem_id,
					min(gather->words - i,
					    TRACE_MAX_LENGTH),
					gather->offset + i * sizeof(u32),
					mem);
			}
			nvmap_munmap(&handle, mem);
		}
	}
}
Esempio n. 2
0
void tegra_pcm_deallocate_dma_buffer(struct snd_pcm *pcm, int stream)
{
	struct snd_pcm_substream *substream;
	struct snd_dma_buffer *buf;
#if TEGRA30_USE_SMMU
	struct tegra_smmu_data *ptsd;
#endif

	substream = pcm->streams[stream].substream;
	if (!substream)
		return;

	buf = &substream->dma_buffer;
	if (!buf->area)
		return;

#if TEGRA30_USE_SMMU
	if (!buf->private_data)
		return;
	ptsd = (struct tegra_smmu_data *)buf->private_data;
	nvmap_unpin(ptsd->pcm_nvmap_client, ptsd->pcm_nvmap_handle);
	nvmap_munmap(ptsd->pcm_nvmap_handle, buf->area);
	nvmap_free(ptsd->pcm_nvmap_client, ptsd->pcm_nvmap_handle);
	kfree(ptsd);
	buf->private_data = NULL;
#else
	dma_free_writecombine(pcm->card->dev, buf->bytes,
				buf->area, buf->addr);
#endif
	buf->area = NULL;
}
static void free_gathers(struct nvhost_job *job)
{
	if (job->gathers) {
		nvmap_munmap(job->gather_mem, job->gathers);
		job->gathers = NULL;
	}
	if (job->gather_mem) {
		nvmap_free(job->nvmap, job->gather_mem);
		job->gather_mem = NULL;
	}
}
Esempio n. 4
0
static void job_free(struct kref *ref)
{
	struct nvhost_job *job = container_of(ref, struct nvhost_job, ref);

	if (job->gathers)
		nvmap_munmap(job->gather_mem, job->gathers);
	if (job->gather_mem)
		nvmap_free(job->nvmap, job->gather_mem);
	if (job->nvmap)
		nvmap_client_put(job->nvmap);
	vfree(job);
}
void nvhost_3dctx_free(struct kref *ref)
{
	struct nvhost_hwctx *ctx = container_of(ref, struct nvhost_hwctx, ref);
	struct nvmap_client *nvmap = ctx->channel->dev->nvmap;

	if (ctx->restore_virt) {
		nvmap_munmap(ctx->restore, ctx->restore_virt);
		ctx->restore_virt = NULL;
	}
	nvmap_unpin(nvmap, ctx->restore);
	ctx->restore_phys = 0;
	nvmap_free(nvmap, ctx->restore);
	ctx->restore = NULL;
	kfree(ctx);
}
struct nvhost_hwctx *nvhost_3dctx_alloc_common(struct nvhost_channel *ch,
					bool map_restore)
{
	struct nvmap_client *nvmap = ch->dev->nvmap;
	struct nvhost_hwctx *ctx;

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return NULL;
	ctx->restore = nvmap_alloc(nvmap, nvhost_3dctx_restore_size * 4, 32,
		map_restore ? NVMAP_HANDLE_WRITE_COMBINE
			    : NVMAP_HANDLE_UNCACHEABLE);
	if (IS_ERR_OR_NULL(ctx->restore))
		goto fail;

	if (map_restore) {
		ctx->restore_virt = nvmap_mmap(ctx->restore);
		if (!ctx->restore_virt)
			goto fail;
	} else
		ctx->restore_virt = NULL;

	kref_init(&ctx->ref);
	ctx->channel = ch;
	ctx->valid = false;
	ctx->save = nvhost_3dctx_save_buf;
	ctx->save_incrs = nvhost_3dctx_save_incrs;
	ctx->save_thresh = nvhost_3dctx_save_thresh;
	ctx->save_slots = nvhost_3dctx_save_slots;
	ctx->restore_phys = nvmap_pin(nvmap, ctx->restore);
	if (IS_ERR_VALUE(ctx->restore_phys))
		goto fail;

	ctx->restore_size = nvhost_3dctx_restore_size;
	ctx->restore_incrs = nvhost_3dctx_restore_incrs;
	return ctx;

fail:
	if (map_restore && ctx->restore_virt) {
		nvmap_munmap(ctx->restore, ctx->restore_virt);
		ctx->restore_virt = NULL;
	}
	nvmap_free(nvmap, ctx->restore);
	ctx->restore = NULL;
	kfree(ctx);
	return NULL;
}
Esempio n. 7
0
static int nvhost_channelrelease(struct inode *inode, struct file *filp)
{
	struct nvhost_channel_userctx *priv = filp->private_data;

	trace_nvhost_channel_release(priv->ch->desc->name);

	filp->private_data = NULL;

	nvhost_module_remove_client(priv->ch->dev, &priv->ch->mod, priv);
	nvhost_putchannel(priv->ch, priv->hwctx);

	if (priv->hwctx)
		priv->ch->ctxhandler.put(priv->hwctx);

	if (priv->gathers)
		nvmap_munmap(priv->gather_mem, priv->gathers);

	if (!IS_ERR_OR_NULL(priv->gather_mem))
		nvmap_free(priv->ch->dev->nvmap, priv->gather_mem);

	nvmap_client_put(priv->nvmap);
	kfree(priv);
	return 0;
}
Esempio n. 8
0
void nvhost_nvmap_munmap(struct mem_handle *handle, void *addr)
{
	nvmap_munmap((struct nvmap_handle_ref *)handle, addr);
}