summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/host/nvhost_cdma.h
diff options
context:
space:
mode:
authorGary King <gking@nvidia.com>2010-08-31 15:51:55 -0700
committerRebecca Schultz Zavin <rebecca@android.com>2010-10-08 15:59:01 -0700
commite5bc8c86174f909e5323167bbe9605c667d31b1a (patch)
treedead8de5a5cd52535c5f5f58459c722bc5941898 /drivers/video/tegra/host/nvhost_cdma.h
parent10c751b8f5bb78f674d4939b47be933934bb23dd (diff)
video: tegra: host1x driver
the graphics and display hardware on tegra SoCs is accessed through a command DMA front-end called host1x host driver clients place commands into memory objects called streams, and submit a stream on one of 8 channels: the assignment of streams-to-channels depends on the hardware module(s) programmed by the stream: for example, all streams which program the 3D hardware are submitted on channel 1. the host1x hardware includes two synchronization primitives to allow command streams to synchronize access to memory or to hardware engines shared across channels (e.g. the 2D blitter): sync points and module mutexes. both primitives can also be used to synchronize with the CPU. the host1x driver performs power management for all modules behind the host block: once a module is idle (i.e., the last stream which accesses it has completed, indicated by a syncpoint) and has remained idle for an extended period of time, the module's clock (and power gate island, if the module is uniquely power-gated) is disabled, and will be automatically re-enabled when a new stream is submitted for that module. includes channel debugging support originally implemented by Erik Gilling <konkers@google.com> Original Author: Antti Hatala <ahatala@nvidia.com> Signed-off-by: Gary King <gking@nvidia.com> Change-Id: Idf0ecc8e7710f3839903a9fbfbe5650990a96b2c
Diffstat (limited to 'drivers/video/tegra/host/nvhost_cdma.h')
-rw-r--r--drivers/video/tegra/host/nvhost_cdma.h101
1 files changed, 101 insertions, 0 deletions
diff --git a/drivers/video/tegra/host/nvhost_cdma.h b/drivers/video/tegra/host/nvhost_cdma.h
new file mode 100644
index 000000000000..77493abe0e27
--- /dev/null
+++ b/drivers/video/tegra/host/nvhost_cdma.h
@@ -0,0 +1,101 @@
+/*
+ * drivers/video/tegra/host/nvhost_cdma.h
+ *
+ * Tegra Graphics Host Command DMA
+ *
+ * Copyright (c) 2010, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __NVHOST_CDMA_H
+#define __NVHOST_CDMA_H
+
+#include <linux/sched.h>
+#include <linux/semaphore.h>
+
+#include <mach/nvhost.h>
+#include <mach/nvmap.h>
+
+#include "nvhost_acm.h"
+
+/*
+ * cdma
+ *
+ * This is in charge of a host command DMA channel.
+ * Sends ops to a push buffer, and takes responsibility for unpinning
+ * (& possibly freeing) of memory after those ops have completed.
+ * Producer:
+ * begin
+ * push - send ops to the push buffer
+ * end - start command DMA and enqueue handles to be unpinned
+ * Consumer:
+ * update - call to update sync queue and push buffer, unpin memory
+ */
+
+/* Size of the sync queue. If it is too small, we won't be able to queue up
+ * many command buffers. If it is too large, we waste memory. */
+#define NVHOST_SYNC_QUEUE_SIZE 8192
+
+/* Number of gathers we allow to be queued up per channel. Must be a
+ power of two. Currently sized such that pushbuffer is 4KB (512*8B). */
+#define NVHOST_GATHER_QUEUE_SIZE 512
+
+struct push_buffer {
+ struct nvmap_handle_ref *mem; /* handle to pushbuffer memory */
+ u32 *mapped; /* mapped pushbuffer memory */
+ u32 phys; /* physical address of pushbuffer */
+ u32 fence; /* index we've written */
+ u32 cur; /* index to write to */
+};
+
+struct sync_queue {
+ unsigned int read; /* read position within buffer */
+ unsigned int write; /* write position within buffer */
+ u32 buffer[NVHOST_SYNC_QUEUE_SIZE]; /* queue data */
+};
+
+enum cdma_event {
+ CDMA_EVENT_NONE, /* not waiting for any event */
+ CDMA_EVENT_SYNC_QUEUE_EMPTY, /* wait for empty sync queue */
+ CDMA_EVENT_SYNC_QUEUE_SPACE, /* wait for space in sync queue */
+ CDMA_EVENT_PUSH_BUFFER_SPACE /* wait for space in push buffer */
+};
+
+struct nvhost_cdma {
+ struct mutex lock; /* controls access to shared state */
+ struct semaphore sem; /* signalled when event occurs */
+ enum cdma_event event; /* event that sem is waiting for */
+ unsigned int slots_used; /* pb slots used in current submit */
+ unsigned int slots_free; /* pb slots free in current submit */
+ unsigned int last_put; /* last value written to DMAPUT */
+ struct push_buffer push_buffer; /* channel's push buffer */
+ struct sync_queue sync_queue; /* channel's sync queue */
+ bool running;
+};
+
+int nvhost_cdma_init(struct nvhost_cdma *cdma);
+void nvhost_cdma_deinit(struct nvhost_cdma *cdma);
+void nvhost_cdma_stop(struct nvhost_cdma *cdma);
+void nvhost_cdma_begin(struct nvhost_cdma *cdma);
+void nvhost_cdma_push(struct nvhost_cdma *cdma, u32 op1, u32 op2);
+void nvhost_cdma_end(struct nvmap_client *user_nvmap,
+ struct nvhost_cdma *cdma,
+ u32 sync_point_id, u32 sync_point_value,
+ struct nvmap_handle **handles, unsigned int nr_handles);
+void nvhost_cdma_update(struct nvhost_cdma *cdma);
+void nvhost_cdma_flush(struct nvhost_cdma *cdma);
+
+#endif