* [RFC,libdrm 1/3] tegra: Add stream library
2012-12-13 14:01 [RFC,libdrm 0/3] NVIDIA Tegra support Arto Meriläinen
@ 2012-12-13 14:01 ` Arto Meriläinen
[not found] ` <1355407268-32381-2-git-send-email-amerilainen-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-12-13 14:01 ` [RFC,libdrm 2/3] tegra: Add 2d library Arto Meriläinen
2012-12-13 14:01 ` [RFC,libdrm 3/3] tests: tegra: Add 2d tests Arto Meriläinen
2 siblings, 1 reply; 16+ messages in thread
From: Arto Meriläinen @ 2012-12-13 14:01 UTC (permalink / raw)
To: thierry.reding, dri-devel, linux-tegra; +Cc: fhart, tbergstrom
From: Arto Merilainen <amerilainen@nvidia.com>
This patch introduces tegra stream library. The library is used for
buffer management, command stream construction and work
synchronization.
Signed-off-by: Arto Merilainen <amerilainen@nvidia.com>
---
Makefile.am | 6 +-
configure.ac | 13 +
tegra/Makefile.am | 25 ++
tegra/class_ids.h | 35 ++
tegra/host1x01_hardware.h | 122 ++++++
tegra/hw_host1x01_uclass.h | 143 ++++++++
tegra/libdrm_tegra.pc.in | 10 +
tegra/tegra_drm.c | 876 ++++++++++++++++++++++++++++++++++++++++++++
tegra/tegra_drm.h | 142 +++++++
tegra/tegra_drmif.h | 107 ++++++
10 files changed, 1478 insertions(+), 1 deletion(-)
create mode 100644 tegra/Makefile.am
create mode 100644 tegra/class_ids.h
create mode 100644 tegra/host1x01_hardware.h
create mode 100644 tegra/hw_host1x01_uclass.h
create mode 100644 tegra/libdrm_tegra.pc.in
create mode 100644 tegra/tegra_drm.c
create mode 100644 tegra/tegra_drm.h
create mode 100644 tegra/tegra_drmif.h
diff --git a/Makefile.am b/Makefile.am
index 8ecd9d9..e90ae43 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -49,7 +49,11 @@ if HAVE_EXYNOS
EXYNOS_SUBDIR = exynos
endif
-SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) tests include man
+if HAVE_TEGRA
+TEGRA_SUBDIR = tegra
+endif
+
+SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) $(TEGRA_SUBDIR) tests include man
libdrm_la_LTLIBRARIES = libdrm.la
libdrm_ladir = $(libdir)
diff --git a/configure.ac b/configure.ac
index 0c19929..36c55c7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -114,6 +114,11 @@ AC_ARG_ENABLE(exynos-experimental-api,
[Enable support for EXYNOS's experimental API (default: disabled)]),
[EXYNOS=$enableval], [EXYNOS=no])
+AC_ARG_ENABLE(tegra,
+ AS_HELP_STRING([--enable-tegra],
+ [Enable support for tegra's API (default: disabled)]),
+ [TEGRA=$enableval], [TEGRA=no])
+
dnl ===========================================================================
dnl check compiler flags
AC_DEFUN([LIBDRM_CC_TRY_FLAG], [
@@ -222,6 +227,11 @@ if test "x$EXYNOS" = xyes; then
AC_DEFINE(HAVE_EXYNOS, 1, [Have EXYNOS support])
fi
+AM_CONDITIONAL(HAVE_TEGRA, [test "x$TEGRA" = xyes])
+if test "x$TEGRA" = xyes; then
+ AC_DEFINE(HAVE_TEGRA, 1, [Have TEGRA support])
+fi
+
AC_ARG_ENABLE([cairo-tests],
[AS_HELP_STRING([--enable-cairo-tests],
[Enable support for Cairo rendering in tests (default: auto)])],
@@ -358,6 +368,8 @@ AC_CONFIG_FILES([
omap/libdrm_omap.pc
exynos/Makefile
exynos/libdrm_exynos.pc
+ tegra/Makefile
+ tegra/libdrm_tegra.pc
tests/Makefile
tests/modeprint/Makefile
tests/modetest/Makefile
@@ -380,4 +392,5 @@ echo " Radeon API $RADEON"
echo " Nouveau API $NOUVEAU"
echo " OMAP API $OMAP"
echo " EXYNOS API $EXYNOS"
+echo " TEGRA API $TEGRA"
echo ""
diff --git a/tegra/Makefile.am b/tegra/Makefile.am
new file mode 100644
index 0000000..72675e5
--- /dev/null
+++ b/tegra/Makefile.am
@@ -0,0 +1,25 @@
+AM_CFLAGS = \
+ $(WARN_CFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/tegra \
+ $(PTHREADSTUBS_CFLAGS) \
+ -I$(top_srcdir)/include/drm
+
+libdrm_tegra_la_LTLIBRARIES = libdrm_tegra.la
+libdrm_tegra_ladir = $(libdir)
+libdrm_tegra_la_LDFLAGS = -version-number 1:0:0 -no-undefined
+libdrm_tegra_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
+
+libdrm_tegra_la_SOURCES = \
+ tegra_drm.c
+
+libdrm_tegracommonincludedir = ${includedir}/tegra
+libdrm_tegracommoninclude_HEADERS = \
+ tegra_drm.h
+
+libdrm_tegraincludedir = ${includedir}/libdrm
+libdrm_tegrainclude_HEADERS = \
+ tegra_drmif.h
+
+pkgconfigdir = @pkgconfigdir@
+pkgconfig_DATA = libdrm_tegra.pc
diff --git a/tegra/class_ids.h b/tegra/class_ids.h
new file mode 100644
index 0000000..834e291
--- /dev/null
+++ b/tegra/class_ids.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __NVHOST_CLASS_IDS_H
+#define __NVHOST_CLASS_IDS_H
+
+
+enum {
+ NV_HOST1X_CLASS_ID = 0x1,
+ NV_GRAPHICS_2D_CLASS_ID = 0x51,
+ NV_GRAPHICS_2D_SB_CLASS_ID = 0x52,
+};
+
+#endif /*__NVHOST_CLASS_IDS_H */
diff --git a/tegra/host1x01_hardware.h b/tegra/host1x01_hardware.h
new file mode 100644
index 0000000..5f94d52
--- /dev/null
+++ b/tegra/host1x01_hardware.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Arto Merilainen <amerilainen@nvidia.com>
+ */
+
+#ifndef __NVHOST_HOST1X01_HARDWARE_H
+#define __NVHOST_HOST1X01_HARDWARE_H
+
+#include <linux/types.h>
+#include "hw_host1x01_uclass.h"
+
+/* channel registers */
+#define NV_HOST1X_CHANNEL_MAP_SIZE_BYTES 16384
+#define NV_HOST1X_SYNC_MLOCK_NUM 16
+
+/* sync registers */
+#define HOST1X_CHANNEL_SYNC_REG_BASE 0x3000
+#define NV_HOST1X_NB_MLOCKS 16
+
+#define BIT(nr) (1UL << (nr))
+
+static inline uint32_t nvhost_class_host_wait_syncpt(
+ unsigned indx, unsigned threshold)
+{
+ return host1x_uclass_wait_syncpt_indx_f(indx)
+ | host1x_uclass_wait_syncpt_thresh_f(threshold);
+}
+
+static inline uint32_t nvhost_class_host_load_syncpt_base(
+ unsigned indx, unsigned threshold)
+{
+ return host1x_uclass_load_syncpt_base_base_indx_f(indx)
+ | host1x_uclass_load_syncpt_base_value_f(threshold);
+}
+
+static inline uint32_t nvhost_class_host_wait_syncpt_base(
+ unsigned indx, unsigned base_indx, unsigned offset)
+{
+ return host1x_uclass_wait_syncpt_base_indx_f(indx)
+ | host1x_uclass_wait_syncpt_base_base_indx_f(base_indx)
+ | host1x_uclass_wait_syncpt_base_offset_f(offset);
+}
+
+static inline uint32_t nvhost_class_host_incr_syncpt_base(
+ unsigned base_indx, unsigned offset)
+{
+ return host1x_uclass_incr_syncpt_base_base_indx_f(base_indx)
+ | host1x_uclass_incr_syncpt_base_offset_f(offset);
+}
+
+static inline uint32_t nvhost_class_host_incr_syncpt(
+ unsigned cond, unsigned indx)
+{
+ return host1x_uclass_incr_syncpt_cond_f(cond)
+ | host1x_uclass_incr_syncpt_indx_f(indx);
+}
+
+static inline uint32_t nvhost_class_host_indoff_reg_write(
+ unsigned mod_id, unsigned offset, int auto_inc)
+{
+ uint32_t v = host1x_uclass_indoff_indbe_f(0xf)
+ | host1x_uclass_indoff_indmodid_f(mod_id)
+ | host1x_uclass_indoff_indroffset_f(offset);
+ if (auto_inc)
+ v |= host1x_uclass_indoff_autoinc_f(1);
+ return v;
+}
+
+static inline uint32_t nvhost_class_host_indoff_reg_read(
+ unsigned mod_id, unsigned offset, int auto_inc)
+{
+ uint32_t v = host1x_uclass_indoff_indmodid_f(mod_id)
+ | host1x_uclass_indoff_indroffset_f(offset)
+ | host1x_uclass_indoff_rwn_read_v();
+ if (auto_inc)
+ v |= host1x_uclass_indoff_autoinc_f(1);
+ return v;
+}
+
+
+/* cdma opcodes */
+static inline uint32_t nvhost_opcode_setclass(
+ unsigned class_id, unsigned offset, unsigned mask)
+{
+ return (0 << 28) | (offset << 16) | (class_id << 6) | mask;
+}
+static inline uint32_t nvhost_opcode_nonincr(unsigned offset, unsigned count)
+{
+ return (2 << 28) | (offset << 16) | count;
+}
+
+static inline uint32_t nvhost_opcode_mask(unsigned offset, unsigned mask)
+{
+ return (3 << 28) | (offset << 16) | mask;
+}
+
+static inline uint32_t nvhost_mask2(unsigned x, unsigned y)
+{
+ return 1 | (1 << (y - x));
+}
+#endif
diff --git a/tegra/hw_host1x01_uclass.h b/tegra/hw_host1x01_uclass.h
new file mode 100644
index 0000000..ba8c2d5
--- /dev/null
+++ b/tegra/hw_host1x01_uclass.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Arto Merilainen <amerilainen@nvidia.com>
+ */
+
+ /*
+ * Function naming determines intended use:
+ *
+ * <x>_r(void) : Returns the offset for register <x>.
+ *
+ * <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
+ *
+ * <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
+ *
+ * <x>_<y>_f(uint32_t v) : Returns a value based on 'v' which has been shifted
+ * and masked to place it at field <y> of register <x>. This value
+ * can be |'d with others to produce a full register value for
+ * register <x>.
+ *
+ * <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
+ * value can be ~'d and then &'d to clear the value of field <y> for
+ * register <x>.
+ *
+ * <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
+ * to place it at field <y> of register <x>. This value can be |'d
+ * with others to produce a full register value for <x>.
+ *
+ * <x>_<y>_v(uint32_t r) : Returns the value of field <y> from a full register
+ * <x> value 'r' after being shifted to place its LSB at bit 0.
+ * This value is suitable for direct comparison with other unshifted
+ * values appropriate for use in field <y> of register <x>.
+ *
+ * <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
+ * field <y> of register <x>. This value is suitable for direct
+ * comparison with unshifted values appropriate for use in field <y>
+ * of register <x>.
+ */
+
+#ifndef __hw_host1x_uclass_host1x_h__
+#define __hw_host1x_uclass_host1x_h__
+
+static inline uint32_t host1x_uclass_incr_syncpt_r(void)
+{
+ return 0x0;
+}
+static inline uint32_t host1x_uclass_incr_syncpt_cond_f(uint32_t v)
+{
+ return (v & 0xff) << 8;
+}
+static inline uint32_t host1x_uclass_incr_syncpt_cond_op_done_v(void)
+{
+ return 1;
+}
+static inline uint32_t host1x_uclass_incr_syncpt_indx_f(uint32_t v)
+{
+ return (v & 0xff) << 0;
+}
+static inline uint32_t host1x_uclass_wait_syncpt_r(void)
+{
+ return 0x8;
+}
+static inline uint32_t host1x_uclass_wait_syncpt_indx_f(uint32_t v)
+{
+ return (v & 0xff) << 24;
+}
+static inline uint32_t host1x_uclass_wait_syncpt_thresh_f(uint32_t v)
+{
+ return (v & 0xffffff) << 0;
+}
+static inline uint32_t host1x_uclass_wait_syncpt_base_indx_f(uint32_t v)
+{
+ return (v & 0xff) << 24;
+}
+static inline uint32_t host1x_uclass_wait_syncpt_base_base_indx_f(uint32_t v)
+{
+ return (v & 0xff) << 16;
+}
+static inline uint32_t host1x_uclass_wait_syncpt_base_offset_f(uint32_t v)
+{
+ return (v & 0xffff) << 0;
+}
+static inline uint32_t host1x_uclass_load_syncpt_base_base_indx_f(uint32_t v)
+{
+ return (v & 0xff) << 24;
+}
+static inline uint32_t host1x_uclass_load_syncpt_base_value_f(uint32_t v)
+{
+ return (v & 0xffffff) << 0;
+}
+static inline uint32_t host1x_uclass_incr_syncpt_base_base_indx_f(uint32_t v)
+{
+ return (v & 0xff) << 24;
+}
+static inline uint32_t host1x_uclass_incr_syncpt_base_offset_f(uint32_t v)
+{
+ return (v & 0xffffff) << 0;
+}
+static inline uint32_t host1x_uclass_indoff_r(void)
+{
+ return 0x2d;
+}
+static inline uint32_t host1x_uclass_indoff_indbe_f(uint32_t v)
+{
+ return (v & 0xf) << 28;
+}
+static inline uint32_t host1x_uclass_indoff_autoinc_f(uint32_t v)
+{
+ return (v & 0x1) << 27;
+}
+static inline uint32_t host1x_uclass_indoff_indmodid_f(uint32_t v)
+{
+ return (v & 0xff) << 18;
+}
+static inline uint32_t host1x_uclass_indoff_indroffset_f(uint32_t v)
+{
+ return (v & 0xffff) << 2;
+}
+static inline uint32_t host1x_uclass_indoff_rwn_read_v(void)
+{
+ return 1;
+}
+#endif /* __hw_host1x_uclass_host1x_h__ */
diff --git a/tegra/libdrm_tegra.pc.in b/tegra/libdrm_tegra.pc.in
new file mode 100644
index 0000000..3ad8c6f
--- /dev/null
+++ b/tegra/libdrm_tegra.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libdrm_tegra
+Description: Userspace interface to tegra kernel DRM services
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -ldrm_tegra
+Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/tegra
diff --git a/tegra/tegra_drm.c b/tegra/tegra_drm.c
new file mode 100644
index 0000000..ad3a90e
--- /dev/null
+++ b/tegra/tegra_drm.c
@@ -0,0 +1,876 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Arto Merilainen <amerilainen@nvidia.com>
+ */
+
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include <drm.h>
+#include <xf86drm.h>
+
+#include "tegra_drmif.h"
+#include "tegra_drm.h"
+
+#include "class_ids.h"
+#include "hw_host1x01_uclass.h"
+#include "host1x01_hardware.h"
+
+/*
+ * stream library configuration
+ *
+ * NUMBER_OF_BUFFERS - Determine the number of preallocated command buffers
+ * RELOC_TABLE_SIZE - Maximum number of memory references in a command buffer
+ * BUFFER_SIZE_WORDS - Define the size of command buffers
+ */
+
+#define NUMBER_OF_BUFFERS 4
+#define RELOC_TABLE_SIZE 128
+#define BUFFER_SIZE_WORDS 1024
+
+enum tegra_stream_status {
+ TEGRADRM_STREAM_FREE,
+ TEGRADRM_STREAM_CONSTRUCT,
+ TEGRADRM_STREAM_READY
+};
+
+struct tegra_device {
+ int fd;
+};
+
+struct tegra_bo {
+
+ struct tegra_device *dev;
+
+ void *vaddr;
+
+ uint32_t gem_handle;
+ unsigned int offset;
+
+ uint32_t size;
+};
+
+struct tegra_channel {
+
+ struct tegra_device *dev;
+
+ uint64_t context;
+
+ enum tegra_module_id module_id;
+ uint32_t default_class_id;
+
+ uint32_t syncpt_id;
+};
+
+struct tegra_command_buffer {
+
+ struct tegra_bo *mem;
+
+ struct tegra_drm_reloc *reloc_table;
+ uint32_t *data;
+
+ uint32_t cmd_ptr;
+ uint32_t reloc_ptr;
+
+ uint64_t syncpt_max;
+
+ int flushed;
+};
+
+struct tegra_stream {
+
+ enum tegra_stream_status status;
+
+ struct tegra_channel *channel;
+ int num_words;
+ int num_relocs;
+ uint32_t num_syncpt_incrs;
+
+ struct tegra_command_buffer buffers[NUMBER_OF_BUFFERS];
+ struct tegra_command_buffer *active_buffer;
+ unsigned int active_buffer_idx;
+
+ uint32_t current_class_id;
+};
+
+/*
+ * tegra_next_buffer(stream)
+ *
+ * Move to use next command buffer. NOTE! This routine does not verify that the
+ * new buffer is ready to use.
+ */
+
+static void tegra_next_buffer(struct tegra_stream *stream)
+{
+ stream->active_buffer_idx = (stream->active_buffer_idx + 1) %
+ NUMBER_OF_BUFFERS;
+ stream->active_buffer = &stream->buffers[stream->active_buffer_idx];
+}
+
+/*
+ * tegra_device_create(fd)
+ *
+ * Create a device "object" representing tegra drm device. The device should be
+ * opened using i.e. drmOpen(). If object cannot be created, NULL is returned
+ */
+
+struct tegra_device *tegra_device_create(int fd)
+{
+ struct tegra_device *dev;
+
+ if (!(dev = malloc(sizeof(dev))))
+ goto err_dev_alloc;
+ dev->fd = fd;
+
+ return dev;
+
+err_dev_alloc:
+ return NULL;
+}
+
+/*
+ * tegra_device_destroy(dev)
+ *
+ * Remove device object created using tegra_device_create(). The caller is
+ * responsible for calling drmClose().
+ */
+
+void tegra_device_destroy(struct tegra_device *dev)
+{
+ if (!dev)
+ return;
+ free(dev);
+}
+
+/*
+ * tegra_channel_open(dev, module_id)
+ *
+ * Reserve channel resources for given module. Host1x has several channels
+ * each of which is dedicated for a certain hardware module. The opened
+ * channel is used by streams for delivering command buffers.
+ */
+
+struct tegra_channel *tegra_channel_open(
+ struct tegra_device *dev,
+ enum tegra_module_id module_id)
+{
+ struct tegra_channel *channel;
+ struct tegra_drm_get_channel_param_args get_args;
+ struct tegra_drm_open_channel_args open_args;
+ uint32_t default_class_id;
+
+ if (!(channel = malloc(sizeof(*channel))))
+ goto err_channel_alloc;
+
+ switch (module_id) {
+ case TEGRADRM_MODULEID_2D:
+ default_class_id = NV_GRAPHICS_2D_CLASS_ID;
+ break;
+ default:
+ return NULL;
+ }
+
+ channel->module_id = module_id;
+ channel->default_class_id = default_class_id;
+
+ open_args.class = default_class_id;
+ if (drmIoctl(dev->fd, DRM_IOCTL_TEGRA_DRM_OPEN_CHANNEL, &open_args))
+ goto err_channel_open;
+
+ channel->context = open_args.context;
+ get_args.context = open_args.context;
+ get_args.param = 0;
+
+ if (drmIoctl(dev->fd, DRM_IOCTL_TEGRA_DRM_GET_SYNCPOINT,
+ &get_args))
+ goto err_tegra_ioctl;
+ channel->syncpt_id = get_args.value;
+
+ channel->dev = dev;
+
+ return channel;
+
+err_tegra_ioctl:
+ drmIoctl(dev->fd, DRM_IOCTL_TEGRA_DRM_CLOSE_CHANNEL, &open_args);
+err_channel_open:
+ free(channel);
+err_channel_alloc:
+ return NULL;
+}
+
+/*
+ * tegra_channel_close(channel)
+ *
+ * Close a channel.
+ */
+
+void tegra_channel_close(struct tegra_channel *channel)
+{
+ struct tegra_drm_open_channel_args close_args;
+
+ if (!channel)
+ return;
+
+ close_args.class = channel->default_class_id;
+ close_args.context = channel->context;
+
+ drmIoctl(channel->dev->fd, DRM_IOCTL_TEGRA_DRM_CLOSE_CHANNEL,
+ &close_args);
+
+ free(channel);
+}
+
+/*
+ * tegra_stream_create(channel)
+ *
+ * Create a stream for given channel. This function preallocates several
+ * command buffers for later usage to improve performance. Streams are
+ * used for generating command buffers opcode by opcode using
+ * tegra_stream_push*().
+ */
+
+struct tegra_stream *tegra_stream_create(
+ struct tegra_channel *channel)
+{
+ struct tegra_stream *stream;
+ int i;
+
+ if (!channel)
+ goto err_bad_channel;
+
+ if (!(stream = malloc(sizeof(*stream))))
+ goto err_alloc_stream;
+
+ memset(stream, '\0', sizeof(*stream));
+ stream->channel = channel;
+ stream->status = TEGRADRM_STREAM_FREE;
+
+ for (i = 0; i < NUMBER_OF_BUFFERS; i++) {
+ struct tegra_command_buffer *buffer = &stream->buffers[i];
+
+ if (!(buffer->mem = tegra_bo_allocate(stream->channel->dev,
+ sizeof(uint32_t) * BUFFER_SIZE_WORDS, 4)))
+ goto err_buffer_create;
+
+ if(!(buffer->data = tegra_bo_map(buffer->mem)))
+ goto err_buffer_create;
+
+ if (!(buffer->reloc_table =
+ malloc(RELOC_TABLE_SIZE * sizeof(struct tegra_drm_reloc))))
+ goto err_buffer_create;
+
+ buffer->reloc_ptr = 0;
+ buffer->cmd_ptr = 0;
+ }
+
+ stream->active_buffer_idx = 0;
+ stream->active_buffer = &stream->buffers[0];
+
+ return stream;
+
+err_buffer_create:
+ for (i = 0; i < NUMBER_OF_BUFFERS; i++) {
+ free(stream->buffers[i].reloc_table);
+ tegra_bo_free(stream->buffers[i].mem);
+ }
+ free(stream);
+err_alloc_stream:
+err_bad_channel:
+ return NULL;
+}
+
+/*
+ * tegra_stream_destroy(stream)
+ *
+ * Destroy the given stream object. All resrouces are released.
+ */
+
+void tegra_stream_destroy(struct tegra_stream *stream)
+{
+ int i;
+
+ if (!stream)
+ return;
+
+ for (i = 0; i < NUMBER_OF_BUFFERS; i++) {
+ free(stream->buffers[i].reloc_table);
+ tegra_bo_free(stream->buffers[i].mem);
+ }
+
+ free(stream);
+}
+
+/*
+ * tegra_fence_is_valid(fence)
+ *
+ * Check validity of a fence. We just check that the fence range
+ * is valid w.r.t. host1x hardware.
+ */
+
+int tegra_fence_is_valid(const struct tegra_fence *fence)
+{
+ int valid = fence ? 1 : 0;
+ valid = valid && fence->id != (uint32_t) -1;
+ valid = valid && fence->id < 32;
+ return valid;
+}
+
+/*
+ * tegra_fence_clear(fence)
+ *
+ * Clear (=invalidate) given fence
+ */
+
+void tegra_fence_clear(struct tegra_fence *fence)
+{
+ fence->id = (uint32_t) -1;
+ fence->value = 0;
+}
+
+/*
+ * tegra_fence_copy(dst, src)
+ *
+ * Copy fence
+ */
+
+void tegra_fence_copy(struct tegra_fence *dst, const struct tegra_fence *src)
+{
+ *dst = *src;
+}
+
+/*
+ * tegra_fence_waitex(channel, fence, timeout, value)
+ *
+ * Wait for a given syncpoint value with timeout. The end value is returned in
+ * "value" variable. The function returns 0 if the syncpoint value was
+ * reached before timeout, otherwise an error code.
+ */
+
+int tegra_fence_waitex(struct tegra_channel *channel,
+ struct tegra_fence *fence,
+ long timeout,
+ long *value)
+{
+ struct tegra_drm_syncpt_wait_args args;
+ int err;
+
+ if (!tegra_fence_is_valid(fence))
+ return -EINVAL;
+
+ args.timeout = timeout;
+ args.id = fence->id;
+ args.thresh = fence->value;
+
+ err = drmIoctl(channel->dev->fd, DRM_IOCTL_TEGRA_DRM_SYNCPT_WAIT, &args);
+
+ if (value)
+ *value = args.value;
+
+ return err;
+}
+
+/*
+ * tegra_fence_wait_timeout(channel, fence, timeout)
+ *
+ * Wait for a given syncpoint value with timeout. The function returns 0 if
+ * the syncpoint value was reached before timeout, otherwise an error code.
+ */
+
+int tegra_fence_wait_timeout(struct tegra_channel *channel,
+ struct tegra_fence *fence,
+ long timeout)
+{
+ return tegra_fence_waitex(channel, fence, timeout, NULL);
+}
+
+/*
+ * tegra_fence_wait(channel, wait)
+ *
+ * Wait for a given syncpoint value without timeout.
+ */
+
+int tegra_fence_wait(struct tegra_channel *channel,
+ struct tegra_fence *fence)
+{
+ return tegra_fence_waitex(channel, fence, DRM_TEGRA_NO_TIMEOUT, NULL);
+}
+
+/*
+ * tegra_stream_push_reloc(stream, h, offset)
+ *
+ * Push a memory reference to the stream.
+ */
+
+void tegra_stream_push_reloc(struct tegra_stream *stream,
+ struct tegra_bo *h,
+ int offset)
+{
+ struct tegra_drm_reloc reloc;
+
+ if (!stream || !h)
+ return;
+
+ reloc.cmdbuf_mem = stream->active_buffer->mem->gem_handle;
+ reloc.cmdbuf_offset = stream->active_buffer->cmd_ptr * 4;
+ reloc.target = h->gem_handle;
+ reloc.target_offset = offset;
+ reloc.shift = 0;
+
+ stream->num_words--;
+ stream->num_relocs--;
+ assert(stream->num_words >= 0);
+ assert(stream->status == TEGRADRM_STREAM_CONSTRUCT);
+ stream->active_buffer->data[stream->active_buffer->cmd_ptr++] = 0xDEADBEEF;
+ stream->active_buffer->reloc_table[stream->active_buffer->reloc_ptr++] =
+ reloc;
+}
+
+/*
+ * tegra_bo_gethandle(h)
+ *
+ * Get drm memory handle. This is required if the object is used as a
+ * framebuffer.
+ */
+
+uint32_t tegra_bo_gethandle(struct tegra_bo *h)
+{
+ return h->gem_handle;
+}
+
+/*
+ * tegra_bo_allocate(dev, num_bytes, alignment)
+ *
+ * Allocate num_bytes for host1x device operations. The memory is not
+ * automatically mapped for the application.
+ */
+
+struct tegra_bo *tegra_bo_allocate(struct tegra_device *dev,
+ uint32_t num_bytes,
+ uint32_t alignment)
+{
+ struct tegra_gem_create create;
+ struct tegra_bo *h;
+
+ if (!(h = malloc(sizeof(*h))))
+ goto err_alloc_memory_handle;
+
+ /* Allocate memory */
+ memset(&create, 0, sizeof(create));
+ create.size = num_bytes;
+ if (drmIoctl(dev->fd, DRM_IOCTL_TEGRA_GEM_CREATE, &create))
+ goto err_alloc_memory;
+
+ h->gem_handle = create.handle;
+ h->size = create.size;
+ h->offset = create.offset;
+ h->vaddr = NULL;
+ h->dev = dev;
+
+ return h;
+
+err_alloc_memory:
+ free(h);
+err_alloc_memory_handle:
+ return NULL;
+}
+
+/*
+ * tegra_bo_free(h)
+ *
+ * Release given memory handle. Memory is unmapped if it is mapped. Kernel
+ * takes care of reference counting, so the memory area will not be freed
+ * unless the kernel actually has finished using the area.
+ */
+
+void tegra_bo_free(struct tegra_bo * h)
+{
+ struct drm_gem_close unref;
+
+ if (!h)
+ return;
+
+ tegra_bo_unmap(h);
+ unref.handle = h->gem_handle;
+ drmIoctl(h->dev->fd, DRM_IOCTL_GEM_CLOSE, &unref);
+ free(h);
+}
+
+/*
+ * tegra_bo_map(h)
+ *
+ * Map the given handle for the application.
+ */
+
+void * tegra_bo_map(struct tegra_bo * h)
+{
+ if (!h->vaddr) {
+ h->vaddr = mmap(NULL, h->size, PROT_READ | PROT_WRITE,
+ MAP_SHARED, h->dev->fd, h->offset);
+ }
+
+ return h->vaddr;
+}
+
+/*
+ * tegra_bo_unmap(h)
+ *
+ * Unmap memory from the application. The contents of the memory region is
+ * automatically flushed to the memory
+ */
+
+void tegra_bo_unmap(struct tegra_bo * h)
+{
+ if (!(h && h->vaddr))
+ return;
+
+ munmap(h->vaddr, h->size);
+ h->vaddr = NULL;
+}
+
+/*
+ * tegra_stream_flush(stream, fence)
+ *
+ * Send the current contents of stream buffer. The stream must be
+ * synchronized correctly (we cannot send partial streams). If
+ * pointer to fence is given, the fence will contain the syncpoint value
+ * that is reached when operations in the buffer are finished.
+ */
+
+int tegra_stream_flush(struct tegra_stream *stream,
+ struct tegra_fence *fence)
+{
+ struct tegra_channel *ch = stream->channel;
+ struct tegra_drm_cmdbuf cmdbuf;
+ struct tegra_drm_submit_args submit;
+ struct tegra_drm_syncpt_incr syncpt_incr;
+ struct tegra_command_buffer * buffer = stream->active_buffer;
+ int err;
+
+ if (!stream)
+ return -EINVAL;
+
+ /* Reflushing is fine */
+ if (stream->status == TEGRADRM_STREAM_FREE)
+ return 0;
+
+ /* Crash if stream is constructed badly */
+ assert(stream->status == TEGRADRM_STREAM_READY);
+
+ /* Clean args */
+ memset(&submit, 0, sizeof(submit));
+
+ /* Construct cmd buffer */
+ cmdbuf.mem = buffer->mem->gem_handle;
+ cmdbuf.offset = 0;
+ cmdbuf.words = buffer->cmd_ptr;
+
+ /* Construct syncpoint increments struct */
+ syncpt_incr.syncpt_id = ch->syncpt_id;
+ syncpt_incr.syncpt_incrs = stream->num_syncpt_incrs;
+
+ /* Create submit */
+ submit.context = ch->context;
+ submit.submit_version = 1;
+ submit.num_relocs = buffer->reloc_ptr;
+ submit.num_syncpt_incrs = 1;
+ submit.num_cmdbufs = 1;
+ submit.relocs = (uint32_t)buffer->reloc_table;
+ submit.syncpt_incrs = (uint32_t)&syncpt_incr;
+ submit.cmdbufs = (uint32_t)&cmdbuf;
+
+ /* Push submits to the channel */
+ if ((err = drmIoctl(ch->dev->fd, DRM_IOCTL_TEGRA_DRM_SUBMIT, &submit))) {
+ tegra_fence_clear(fence);
+ return err;
+ }
+
+ /* Return fence */
+ if (fence) {
+ fence->id = ch->syncpt_id;
+ fence->value = submit.fence;
+ }
+
+ stream->num_syncpt_incrs = 0;
+ stream->active_buffer->syncpt_max = submit.fence;
+ stream->active_buffer->flushed = 1;
+ tegra_next_buffer(stream);
+
+ stream->status = TEGRADRM_STREAM_FREE;
+ return 0;
+}
+
+/*
+ * tegra_stream_begin(stream, num_words, fence, num_fences, num_syncpt_incrs,
+ * num_relocs, class_id)
+ *
+ * Start constructing a stream.
+ * - num_words refer to the maximum number of words the stream can contain.
+ * - fence is a pointer to a table that contains syncpoint preconditions
+ * before the stream execution can start.
+ * - num_fences indicate the number of elements in the fence table.
+ * - num_syncpt_incrs indicate the number of syncpoint increments the stream
+ * is doing.
+ * - num_relocs indicate the number of memory references in the buffer.
+ * - class_id refers to the class_id that is selected in the beginning of a
+ * stream. If no class id is given, the default class id (=usually the
+ * client device's class) is selected.
+ *
+ * This function verifies that the current buffer has enough room for holding
+ * the whole stream (this is computed using num_words and num_relocs). The
+ * function blocks until the stream buffer is ready for use.
+ */
+
+int tegra_stream_begin(struct tegra_stream *stream,
+ uint32_t num_words,
+ struct tegra_fence *fence,
+ uint32_t num_fences,
+ uint32_t num_syncpt_incrs,
+ uint32_t num_relocs,
+ uint32_t class_id)
+{
+ if (!stream)
+ return -EINVAL;
+
+ assert(stream->status == TEGRADRM_STREAM_FREE ||
+ stream->status == TEGRADRM_STREAM_READY);
+
+ /* handle class id */
+ if (!class_id && stream->channel->default_class_id)
+ class_id = stream->channel->default_class_id;
+
+ /* include following in num words:
+ * - fence waits in the beginningi ( 1 + num_fences)
+ * - setclass in the beginning (1 word)
+ * - syncpoint increment at the end of the stream (2 words)
+ */
+
+ num_words += 2;
+ num_words += class_id ? 1 : 0;
+ num_words += num_fences ? 1 + num_fences : 0;
+
+ if (num_words + num_relocs > BUFFER_SIZE_WORDS ||
+ num_relocs > RELOC_TABLE_SIZE)
+ return -EINVAL;
+
+ if ((stream->active_buffer->cmd_ptr + num_words + num_relocs >
+ BUFFER_SIZE_WORDS) ||
+ (stream->active_buffer->reloc_ptr + num_relocs > RELOC_TABLE_SIZE)) {
+ tegra_stream_flush(stream, NULL);
+ }
+
+ /* If we are about to start using a new buffer, make sure it is
+ * actually free */
+
+ if (stream->active_buffer->flushed) {
+ struct tegra_fence fence;
+
+ fence.id = stream->channel->syncpt_id;
+ fence.value = stream->active_buffer->syncpt_max;
+ tegra_fence_wait(stream->channel, &fence);
+
+ stream->active_buffer->cmd_ptr = 0;
+ stream->active_buffer->reloc_ptr = 0;
+ stream->active_buffer->flushed = 0;
+ }
+
+ stream->status = TEGRADRM_STREAM_CONSTRUCT;
+ stream->current_class_id = class_id;
+ stream->num_relocs = num_relocs;
+ stream->num_words = num_words;
+ stream->num_syncpt_incrs += num_syncpt_incrs;
+
+ /* Add fences */
+ if (num_fences) {
+
+ tegra_stream_push(stream,
+ nvhost_opcode_setclass(NV_HOST1X_CLASS_ID,
+ host1x_uclass_wait_syncpt_r(), num_fences));
+
+ for (; num_fences; num_fences--, fence++) {
+ assert(tegra_fence_is_valid(fence));
+
+ tegra_stream_push(stream, nvhost_class_host_wait_syncpt(fence->id,
+ fence->value));
+ }
+ }
+
+ if (class_id)
+ tegra_stream_push(stream, nvhost_opcode_setclass(class_id, 0, 0));
+
+ return 0;
+}
+
+/*
+ * tegra_stream_push_setclass(stream, class_id)
+ *
+ * Push "set class" opcode to the stream. Do nothing if the class is already
+ * active
+ */
+
+void tegra_stream_push_setclass(struct tegra_stream *stream,
+ uint32_t class_id)
+{
+ if (stream->current_class_id == class_id)
+ return;
+
+ tegra_stream_push(stream, nvhost_opcode_setclass(class_id, 0, 0));
+ stream->current_class_id = class_id;
+}
+
+/*
+ * tegra_stream_end(stream)
+ *
+ * Mark end of stream. This function pushes last syncpoint increment for
+ * marking end of stream.
+ */
+
+int tegra_stream_end(struct tegra_stream *stream)
+{
+ if (!stream)
+ return -EINVAL;
+
+ /* Add last syncpoint increment on OP_DONE */
+ tegra_stream_push(stream, nvhost_opcode_nonincr(0, 1));
+ tegra_stream_push(stream, nvhost_class_host_incr_syncpt(
+ host1x_uclass_incr_syncpt_cond_op_done_v(),
+ stream->channel->syncpt_id));
+ stream->num_syncpt_incrs += 1;
+
+ assert(stream->status == TEGRADRM_STREAM_CONSTRUCT);
+ stream->status = TEGRADRM_STREAM_READY;
+ return 0;
+}
+
+/*
+ * tegra_stream_push(stream, word)
+ *
+ * Push a single word to given stream.
+ */
+
+void tegra_stream_push(struct tegra_stream *stream, int word)
+{
+ if (!stream)
+ return;
+
+ stream->num_words--;
+ assert(stream->num_words >= 0);
+ assert(stream->status == TEGRADRM_STREAM_CONSTRUCT);
+ stream->active_buffer->data[stream->active_buffer->cmd_ptr++] = word;
+}
+
+/*
+ * tegra_channel_syncpt(channel)
+ *
+ * Get channel syncpoint
+ */
+
+int tegra_channel_syncpt(struct tegra_channel *channel)
+{
+ if (!channel)
+ return -EINVAL;
+
+ return channel->syncpt_id;
+}
+
+/*
+ * tegra_reloc (variable, handle, offset)
+ *
+ * This function creates a reloc allocation. The function should be used in
+ * conjunction with tegra_stream_push_words.
+ */
+
+struct tegra_reloc tegra_reloc(const void *var,
+ const struct tegra_bo *h,
+ const uint32_t offset)
+{
+ struct tegra_reloc reloc = {var, (struct tegra_bo *)h, offset};
+ return reloc;
+
+}
+
+/*
+ * tegra_stream_push_words(stream, addr, words, ...)
+ *
+ * Push words from given address to stream. The function takes
+ * reloc structs as its argument. You can generate the structs with tegra_reloc
+ * function.
+ */
+
+void tegra_stream_push_words(struct tegra_stream *stream,
+ const void *addr, uint32_t words,
+ uint32_t num_relocs, ...)
+{
+ va_list ap;
+ struct tegra_reloc reloc_arg;
+ struct tegra_command_buffer *buffer;
+
+ if (!stream)
+ return;
+
+ buffer = stream->active_buffer;
+
+ stream->num_words -= words;
+ stream->num_relocs -= num_relocs;
+ assert(stream->num_words >= 0 && stream->num_relocs >= 0);
+ assert(stream->status == TEGRADRM_STREAM_CONSTRUCT);
+
+ /* Copy the contents */
+ memcpy(buffer->data + buffer->cmd_ptr, addr,
+ words * sizeof(uint32_t));
+
+ /* Copy relocs */
+ va_start(ap, num_relocs);
+ for (; num_relocs; num_relocs--) {
+
+ uint32_t cmd_ptr;
+ struct tegra_drm_reloc reloc_entry;
+
+ reloc_arg = va_arg(ap, struct tegra_reloc);
+
+ cmd_ptr = buffer->cmd_ptr +
+ ((uint32_t *) reloc_arg.addr) - ((uint32_t *) addr);
+
+ reloc_entry.cmdbuf_mem = buffer->mem->gem_handle;
+ reloc_entry.cmdbuf_offset = cmd_ptr * 4;
+ reloc_entry.target = reloc_arg.h->gem_handle;
+ reloc_entry.target_offset = reloc_arg.offset;
+ reloc_entry.shift = 0;
+
+ buffer->data[cmd_ptr] = 0xDEADBEEF;
+ buffer->reloc_table[buffer->reloc_ptr++] = reloc_entry;
+ }
+ va_end(ap);
+
+ buffer->cmd_ptr += words;
+}
diff --git a/tegra/tegra_drm.h b/tegra/tegra_drm.h
new file mode 100644
index 0000000..358a2fd
--- /dev/null
+++ b/tegra/tegra_drm.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Arto Merilainen <amerilainen@nvidia.com>
+ */
+
+#ifndef _TEGRA_DRM_H_
+#define _TEGRA_DRM_H_
+
+struct tegra_gem_create {
+ __u64 size;
+ unsigned int flags;
+ unsigned int handle;
+ unsigned int offset;
+};
+
+struct tegra_gem_invalidate {
+ unsigned int handle;
+};
+
+struct tegra_gem_flush {
+ unsigned int handle;
+};
+
+struct tegra_drm_syncpt_read_args {
+ __u32 id;
+ __u32 value;
+};
+
+struct tegra_drm_syncpt_incr_args {
+ __u32 id;
+ __u32 pad;
+};
+
+struct tegra_drm_syncpt_wait_args {
+ __u32 id;
+ __u32 thresh;
+ __s32 timeout;
+ __u32 value;
+};
+
+#define DRM_TEGRA_NO_TIMEOUT (-1)
+
+struct tegra_drm_open_channel_args {
+ __u32 class;
+ __u32 pad;
+ __u64 context;
+};
+
+struct tegra_drm_get_channel_param_args {
+ __u64 context;
+ __u32 param;
+ __u32 value;
+};
+
+struct tegra_drm_syncpt_incr {
+ __u32 syncpt_id;
+ __u32 syncpt_incrs;
+};
+
+struct tegra_drm_cmdbuf {
+ __u32 mem;
+ __u32 offset;
+ __u32 words;
+};
+
+struct tegra_drm_reloc {
+ __u32 cmdbuf_mem;
+ __u32 cmdbuf_offset;
+ __u32 target;
+ __u32 target_offset;
+ __u32 shift;
+ __u32 pad;
+};
+
+struct tegra_drm_waitchk {
+ __u32 mem;
+ __u32 offset;
+ __u32 syncpt_id;
+ __u32 thresh;
+};
+
+struct tegra_drm_submit_args {
+ __u64 context;
+ __u32 num_syncpt_incrs;
+ __u32 num_cmdbufs;
+ __u32 num_relocs;
+ __u32 submit_version;
+ __u32 num_waitchks;
+ __u32 waitchk_mask;
+ __u32 timeout;
+ __u32 pad;
+ __u64 syncpt_incrs;
+ __u64 cmdbufs;
+ __u64 relocs;
+ __u64 waitchks;
+ __u32 fence; /* Return value */
+
+ __u32 reserved[5]; /* future expansion */
+};
+
+#define DRM_TEGRA_GEM_CREATE 0x00
+#define DRM_TEGRA_DRM_SYNCPT_READ 0x01
+#define DRM_TEGRA_DRM_SYNCPT_INCR 0x02
+#define DRM_TEGRA_DRM_SYNCPT_WAIT 0x03
+#define DRM_TEGRA_DRM_OPEN_CHANNEL 0x04
+#define DRM_TEGRA_DRM_CLOSE_CHANNEL 0x05
+#define DRM_TEGRA_DRM_GET_SYNCPOINT 0x06
+#define DRM_TEGRA_DRM_GET_MODMUTEXES 0x07
+#define DRM_TEGRA_DRM_SUBMIT 0x08
+
+#define DRM_IOCTL_TEGRA_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_CREATE, struct tegra_gem_create)
+#define DRM_IOCTL_TEGRA_DRM_SYNCPT_READ DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_DRM_SYNCPT_READ, struct tegra_drm_syncpt_read_args)
+#define DRM_IOCTL_TEGRA_DRM_SYNCPT_INCR DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_DRM_SYNCPT_INCR, struct tegra_drm_syncpt_incr_args)
+#define DRM_IOCTL_TEGRA_DRM_SYNCPT_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_DRM_SYNCPT_WAIT, struct tegra_drm_syncpt_wait_args)
+#define DRM_IOCTL_TEGRA_DRM_OPEN_CHANNEL DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_DRM_OPEN_CHANNEL, struct tegra_drm_open_channel_args)
+#define DRM_IOCTL_TEGRA_DRM_CLOSE_CHANNEL DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_DRM_CLOSE_CHANNEL, struct tegra_drm_open_channel_args)
+#define DRM_IOCTL_TEGRA_DRM_GET_SYNCPOINT DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_DRM_GET_SYNCPOINT, struct tegra_drm_get_channel_param_args)
+#define DRM_IOCTL_TEGRA_DRM_GET_MODMUTEXES DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_DRM_GET_MODMUTEXES, struct tegra_drm_get_channel_param_args)
+#define DRM_IOCTL_TEGRA_DRM_SUBMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_DRM_SUBMIT, struct tegra_drm_submit_args)
+
+#endif
diff --git a/tegra/tegra_drmif.h b/tegra/tegra_drmif.h
new file mode 100644
index 0000000..b3f6872
--- /dev/null
+++ b/tegra/tegra_drmif.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Arto Merilainen <amerilainen@nvidia.com>
+ */
+
+#ifndef TEGRA_DRMIF_H
+#define TEGRA_DRMIF_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct tegra_channel;
+struct tegra_bo;
+struct tegra_stream;
+struct tegra_device;
+
+struct tegra_fence {
+ uint32_t id;
+ uint32_t value;
+};
+
+struct tegra_reloc {
+ const void *addr;
+ struct tegra_bo *h;
+ uint32_t offset;
+};
+
+enum tegra_module_id {
+ TEGRADRM_MODULEID_2D
+};
+
+/* Device operations */
+struct tegra_device *tegra_device_create(int fd);
+void tegra_device_destroy(struct tegra_device *dev);
+
+/* Memory operations */
+uint32_t tegra_bo_gethandle(struct tegra_bo *h);
+struct tegra_bo *tegra_bo_allocate(struct tegra_device *dev,
+ uint32_t num_bytes, uint32_t alignment);
+void tegra_bo_free(struct tegra_bo * h);
+void * tegra_bo_map(struct tegra_bo * h);
+void tegra_bo_unmap(struct tegra_bo * h);
+
+/* Channel operations */
+struct tegra_channel *tegra_channel_open(struct tegra_device *dev,
+ enum tegra_module_id module_id);
+void tegra_channel_close(struct tegra_channel *channel);
+int tegra_channel_syncpt(struct tegra_channel *channel);
+
+/* Stream operations */
+struct tegra_stream *tegra_stream_create(struct tegra_channel *channel);
+void tegra_stream_destroy(struct tegra_stream *stream);
+int tegra_stream_begin(struct tegra_stream *stream, uint32_t num_words,
+ struct tegra_fence *fence, uint32_t num_fences,
+ uint32_t num_syncpt_incrs, uint32_t num_relocs,
+ uint32_t class_id);
+int tegra_stream_end(struct tegra_stream *stream);
+int tegra_stream_flush(struct tegra_stream *stream, struct tegra_fence *fence);
+void tegra_stream_push(struct tegra_stream *stream, int word);
+void tegra_stream_push_setclass(struct tegra_stream *stream,
+ uint32_t class_id);
+void tegra_stream_push_reloc(struct tegra_stream *stream, struct tegra_bo *h,
+ int offset);
+struct tegra_reloc tegra_reloc(const void *var, const struct tegra_bo *h,
+ const uint32_t offset);
+void tegra_stream_push_words(struct tegra_stream *stream, const void *addr,
+ uint32_t words, uint32_t num_relocs, ...);
+
+/* Fence operations */
+int tegra_fence_wait(struct tegra_channel *channel, struct tegra_fence *fence);
+int tegra_fence_wait_timeout(struct tegra_channel *channel,
+ struct tegra_fence *fence, long timeout);
+int tegra_fence_waitex(struct tegra_channel *channel, struct tegra_fence *fence,
+ long timeout, long *value);
+int tegra_fence_is_valid(const struct tegra_fence *fence);
+void tegra_fence_clear(struct tegra_fence *fence);
+void tegra_fence_copy(struct tegra_fence *dst, const struct tegra_fence *src);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* TEGRA_DRMIF_H */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 16+ messages in thread* [RFC,libdrm 2/3] tegra: Add 2d library
2012-12-13 14:01 [RFC,libdrm 0/3] NVIDIA Tegra support Arto Meriläinen
2012-12-13 14:01 ` [RFC,libdrm 1/3] tegra: Add stream library Arto Meriläinen
@ 2012-12-13 14:01 ` Arto Meriläinen
[not found] ` <1355407268-32381-3-git-send-email-amerilainen-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-12-13 14:01 ` [RFC,libdrm 3/3] tests: tegra: Add 2d tests Arto Meriläinen
2 siblings, 1 reply; 16+ messages in thread
From: Arto Meriläinen @ 2012-12-13 14:01 UTC (permalink / raw)
To: thierry.reding, dri-devel, linux-tegra; +Cc: fhart, tbergstrom
From: Francis Hart <fhart@nvidia.com>
This patch introduces a simple 2d library on top of stream library.
Signed-off-by: Francis Hart <fhart@nvidia.com>
---
tegra/2d/hw_gr2d.h | 2614 ++++++++++++++++++++++++++++++++++++++++++
tegra/2d/tegra_2d_api.c | 235 ++++
tegra/2d/tegra_2d_color.c | 412 +++++++
tegra/2d/tegra_2d_color.h | 51 +
tegra/2d/tegra_2d_context.c | 140 +++
tegra/2d/tegra_2d_context.h | 67 ++
tegra/2d/tegra_2d_copy.c | 209 ++++
tegra/2d/tegra_2d_copy.h | 38 +
tegra/2d/tegra_2d_fill.c | 136 +++
tegra/2d/tegra_2d_fill.h | 36 +
tegra/2d/tegra_2d_frcopy.c | 274 +++++
tegra/2d/tegra_2d_frcopy.h | 85 ++
tegra/2d/tegra_2d_g2copy.c | 272 +++++
tegra/2d/tegra_2d_g2copy.h | 88 ++
tegra/2d/tegra_2d_g2fill.c | 192 ++++
tegra/2d/tegra_2d_g2fill.h | 80 ++
tegra/2d/tegra_2d_reg_g2sb.h | 89 ++
tegra/2d/tegra_2d_reg_host.h | 119 ++
tegra/2d/tegra_2d_sbcopy.c | 388 +++++++
tegra/2d/tegra_2d_sbcopy.h | 94 ++
tegra/2d/tegra_2d_surface.c | 280 +++++
tegra/2d/tegra_2d_surface.h | 57 +
tegra/2d/tegra_2d_util.c | 145 +++
tegra/2d/tegra_2d_util.h | 89 ++
tegra/Makefile.am | 13 +-
tegra/tegra_2d.h | 223 ++++
26 files changed, 6425 insertions(+), 1 deletion(-)
create mode 100644 tegra/2d/hw_gr2d.h
create mode 100644 tegra/2d/tegra_2d_api.c
create mode 100644 tegra/2d/tegra_2d_color.c
create mode 100644 tegra/2d/tegra_2d_color.h
create mode 100644 tegra/2d/tegra_2d_context.c
create mode 100644 tegra/2d/tegra_2d_context.h
create mode 100644 tegra/2d/tegra_2d_copy.c
create mode 100644 tegra/2d/tegra_2d_copy.h
create mode 100644 tegra/2d/tegra_2d_fill.c
create mode 100644 tegra/2d/tegra_2d_fill.h
create mode 100644 tegra/2d/tegra_2d_frcopy.c
create mode 100644 tegra/2d/tegra_2d_frcopy.h
create mode 100644 tegra/2d/tegra_2d_g2copy.c
create mode 100644 tegra/2d/tegra_2d_g2copy.h
create mode 100644 tegra/2d/tegra_2d_g2fill.c
create mode 100644 tegra/2d/tegra_2d_g2fill.h
create mode 100644 tegra/2d/tegra_2d_reg_g2sb.h
create mode 100644 tegra/2d/tegra_2d_reg_host.h
create mode 100644 tegra/2d/tegra_2d_sbcopy.c
create mode 100644 tegra/2d/tegra_2d_sbcopy.h
create mode 100644 tegra/2d/tegra_2d_surface.c
create mode 100644 tegra/2d/tegra_2d_surface.h
create mode 100644 tegra/2d/tegra_2d_util.c
create mode 100644 tegra/2d/tegra_2d_util.h
create mode 100644 tegra/tegra_2d.h
diff --git a/tegra/2d/hw_gr2d.h b/tegra/2d/hw_gr2d.h
new file mode 100644
index 0000000..4c48feb
--- /dev/null
+++ b/tegra/2d/hw_gr2d.h
@@ -0,0 +1,2614 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+ /*
+ * Function naming determines intended use:
+ *
+ * <x>_r(void) : Returns the offset for register <x>.
+ *
+ * <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
+ *
+ * <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
+ *
+ * <x>_<y>_f(uint32_t v) : Returns a value based on 'v' which has been shifted
+ * and masked to place it at field <y> of register <x>. This value
+ * can be |'d with others to produce a full register value for
+ * register <x>.
+ *
+ * <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
+ * value can be ~'d and then &'d to clear the value of field <y> for
+ * register <x>.
+ *
+ * <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
+ * to place it at field <y> of register <x>. This value can be |'d
+ * with others to produce a full register value for <x>.
+ *
+ * <x>_<y>_v(uint32_t r) : Returns the value of field <y> from a full register
+ * <x> value 'r' after being shifted to place its LSB at bit 0.
+ * This value is suitable for direct comparison with other unshifted
+ * values appropriate for use in field <y> of register <x>.
+ *
+ * <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
+ * field <y> of register <x>. This value is suitable for direct
+ * comparison with unshifted values appropriate for use in field <y>
+ * of register <x>.
+ */
+
+#ifndef __hw_gr2d_h__
+#define __hw_gr2d_h__
+
+static inline uint32_t gr2d_trigger_r(void)
+{
+ return 0x9;
+}
+static inline uint32_t gr2d_trigger_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_trigger_trigger_s(void)
+{
+ return 16;
+}
+static inline uint32_t gr2d_trigger_trigger_f(uint32_t v)
+{
+ return (v & 0xffff) << 0;
+}
+static inline uint32_t gr2d_trigger_trigger_m(void)
+{
+ return 0xffff << 0;
+}
+static inline uint32_t gr2d_trigger_trigger_v(uint32_t r)
+{
+ return (r >> 0) & 0xffff;
+}
+static inline uint32_t gr2d_cmdsel_r(void)
+{
+ return 0xc;
+}
+static inline uint32_t gr2d_cmdsel_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_cmdsel_sbor2d_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_cmdsel_sbor2d_f(uint32_t v)
+{
+ return (v & 0x1) << 0;
+}
+static inline uint32_t gr2d_cmdsel_sbor2d_m(void)
+{
+ return 0x1 << 0;
+}
+static inline uint32_t gr2d_cmdsel_sbor2d_v(uint32_t r)
+{
+ return (r >> 0) & 0x1;
+}
+static inline uint32_t gr2d_cmdsel_sbor2d_g2_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_cmdsel_sbor2d_sb_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_cmdsel_cbenable_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_cmdsel_cbenable_f(uint32_t v)
+{
+ return (v & 0x1) << 4;
+}
+static inline uint32_t gr2d_cmdsel_cbenable_m(void)
+{
+ return 0x1 << 4;
+}
+static inline uint32_t gr2d_cmdsel_cbenable_v(uint32_t r)
+{
+ return (r >> 4) & 0x1;
+}
+static inline uint32_t gr2d_cmdsel_cbenable_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_cmdsel_cbenable_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_cmdsel_vitrigger_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_cmdsel_vitrigger_f(uint32_t v)
+{
+ return (v & 0x1) << 5;
+}
+static inline uint32_t gr2d_cmdsel_vitrigger_m(void)
+{
+ return 0x1 << 5;
+}
+static inline uint32_t gr2d_cmdsel_vitrigger_v(uint32_t r)
+{
+ return (r >> 5) & 0x1;
+}
+static inline uint32_t gr2d_cmdsel_hosttrigger_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_cmdsel_hosttrigger_f(uint32_t v)
+{
+ return (v & 0x1) << 6;
+}
+static inline uint32_t gr2d_cmdsel_hosttrigger_m(void)
+{
+ return 0x1 << 6;
+}
+static inline uint32_t gr2d_cmdsel_hosttrigger_v(uint32_t r)
+{
+ return (r >> 6) & 0x1;
+}
+static inline uint32_t gr2d_cmdsel_cbsbdisable_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_cmdsel_cbsbdisable_f(uint32_t v)
+{
+ return (v & 0x1) << 7;
+}
+static inline uint32_t gr2d_cmdsel_cbsbdisable_m(void)
+{
+ return 0x1 << 7;
+}
+static inline uint32_t gr2d_cmdsel_cbsbdisable_v(uint32_t r)
+{
+ return (r >> 7) & 0x1;
+}
+static inline uint32_t gr2d_cmdsel_g2output_s(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_cmdsel_g2output_f(uint32_t v)
+{
+ return (v & 0x3) << 8;
+}
+static inline uint32_t gr2d_cmdsel_g2output_m(void)
+{
+ return 0x3 << 8;
+}
+static inline uint32_t gr2d_cmdsel_g2output_v(uint32_t r)
+{
+ return (r >> 8) & 0x3;
+}
+static inline uint32_t gr2d_cmdsel_g2output_memory_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_cmdsel_g2output_epp_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_cmdsel_g2output_reserved2_v(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_cmdsel_g2output_reserved3_v(void)
+{
+ return 3;
+}
+static inline uint32_t gr2d_cmdsel_clip_source_top_bottom_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_cmdsel_clip_source_top_bottom_f(uint32_t v)
+{
+ return (v & 0x1) << 10;
+}
+static inline uint32_t gr2d_cmdsel_clip_source_top_bottom_m(void)
+{
+ return 0x1 << 10;
+}
+static inline uint32_t gr2d_cmdsel_clip_source_top_bottom_v(uint32_t r)
+{
+ return (r >> 10) & 0x1;
+}
+static inline uint32_t gr2d_cmdsel_clip_source_top_bottom_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_cmdsel_clip_source_top_bottom_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_cmdsel_frame_start_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_cmdsel_frame_start_f(uint32_t v)
+{
+ return (v & 0x1) << 14;
+}
+static inline uint32_t gr2d_cmdsel_frame_start_m(void)
+{
+ return 0x1 << 14;
+}
+static inline uint32_t gr2d_cmdsel_frame_start_v(uint32_t r)
+{
+ return (r >> 14) & 0x1;
+}
+static inline uint32_t gr2d_cmdsel_frame_end_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_cmdsel_frame_end_f(uint32_t v)
+{
+ return (v & 0x1) << 15;
+}
+static inline uint32_t gr2d_cmdsel_frame_end_m(void)
+{
+ return 0x1 << 15;
+}
+static inline uint32_t gr2d_cmdsel_frame_end_v(uint32_t r)
+{
+ return (r >> 15) & 0x1;
+}
+static inline uint32_t gr2d_cmdsel_buffer_index_s(void)
+{
+ return 8;
+}
+static inline uint32_t gr2d_cmdsel_buffer_index_f(uint32_t v)
+{
+ return (v & 0xff) << 16;
+}
+static inline uint32_t gr2d_cmdsel_buffer_index_m(void)
+{
+ return 0xff << 16;
+}
+static inline uint32_t gr2d_cmdsel_buffer_index_v(uint32_t r)
+{
+ return (r >> 16) & 0xff;
+}
+static inline uint32_t gr2d_cmdsel_linken_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_cmdsel_linken_f(uint32_t v)
+{
+ return (v & 0x1) << 24;
+}
+static inline uint32_t gr2d_cmdsel_linken_m(void)
+{
+ return 0x1 << 24;
+}
+static inline uint32_t gr2d_cmdsel_linken_v(uint32_t r)
+{
+ return (r >> 24) & 0x1;
+}
+static inline uint32_t gr2d_cmdsel_linkval_s(void)
+{
+ return 3;
+}
+static inline uint32_t gr2d_cmdsel_linkval_f(uint32_t v)
+{
+ return (v & 0x7) << 25;
+}
+static inline uint32_t gr2d_cmdsel_linkval_m(void)
+{
+ return 0x7 << 25;
+}
+static inline uint32_t gr2d_cmdsel_linkval_v(uint32_t r)
+{
+ return (r >> 25) & 0x7;
+}
+static inline uint32_t gr2d_cmdsel_priority_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_cmdsel_priority_f(uint32_t v)
+{
+ return (v & 0x1) << 28;
+}
+static inline uint32_t gr2d_cmdsel_priority_m(void)
+{
+ return 0x1 << 28;
+}
+static inline uint32_t gr2d_cmdsel_priority_v(uint32_t r)
+{
+ return (r >> 28) & 0x1;
+}
+static inline uint32_t gr2d_cmdsel_priority_low_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_cmdsel_priority_high_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_vdda_r(void)
+{
+ return 0x11;
+}
+static inline uint32_t gr2d_vdda_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_vdda_vdstep_s(void)
+{
+ return 32;
+}
+static inline uint32_t gr2d_vdda_vdstep_f(uint32_t v)
+{
+ return (v & 0xffffffff) << 0;
+}
+static inline uint32_t gr2d_vdda_vdstep_m(void)
+{
+ return 0xffffffff << 0;
+}
+static inline uint32_t gr2d_vdda_vdstep_v(uint32_t r)
+{
+ return (r >> 0) & 0xffffffff;
+}
+static inline uint32_t gr2d_vddaini_r(void)
+{
+ return 0x12;
+}
+static inline uint32_t gr2d_vddaini_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_vddaini_vdtini_s(void)
+{
+ return 8;
+}
+static inline uint32_t gr2d_vddaini_vdtini_f(uint32_t v)
+{
+ return (v & 0xff) << 0;
+}
+static inline uint32_t gr2d_vddaini_vdtini_m(void)
+{
+ return 0xff << 0;
+}
+static inline uint32_t gr2d_vddaini_vdtini_v(uint32_t r)
+{
+ return (r >> 0) & 0xff;
+}
+static inline uint32_t gr2d_vddaini_vdbini_s(void)
+{
+ return 8;
+}
+static inline uint32_t gr2d_vddaini_vdbini_f(uint32_t v)
+{
+ return (v & 0xff) << 8;
+}
+static inline uint32_t gr2d_vddaini_vdbini_m(void)
+{
+ return 0xff << 8;
+}
+static inline uint32_t gr2d_vddaini_vdbini_v(uint32_t r)
+{
+ return (r >> 8) & 0xff;
+}
+static inline uint32_t gr2d_hdda_r(void)
+{
+ return 0x13;
+}
+static inline uint32_t gr2d_hdda_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_hdda_hdstep_s(void)
+{
+ return 32;
+}
+static inline uint32_t gr2d_hdda_hdstep_f(uint32_t v)
+{
+ return (v & 0xffffffff) << 0;
+}
+static inline uint32_t gr2d_hdda_hdstep_m(void)
+{
+ return 0xffffffff << 0;
+}
+static inline uint32_t gr2d_hdda_hdstep_v(uint32_t r)
+{
+ return (r >> 0) & 0xffffffff;
+}
+static inline uint32_t gr2d_hddainils_r(void)
+{
+ return 0x14;
+}
+static inline uint32_t gr2d_hddainils_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_hddainils_hdini_s(void)
+{
+ return 8;
+}
+static inline uint32_t gr2d_hddainils_hdini_f(uint32_t v)
+{
+ return (v & 0xff) << 0;
+}
+static inline uint32_t gr2d_hddainils_hdini_m(void)
+{
+ return 0xff << 0;
+}
+static inline uint32_t gr2d_hddainils_hdini_v(uint32_t r)
+{
+ return (r >> 0) & 0xff;
+}
+static inline uint32_t gr2d_cscfirst_r(void)
+{
+ return 0x15;
+}
+static inline uint32_t gr2d_cscfirst_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_cscfirst_cub_s(void)
+{
+ return 10;
+}
+static inline uint32_t gr2d_cscfirst_cub_f(uint32_t v)
+{
+ return (v & 0x3ff) << 0;
+}
+static inline uint32_t gr2d_cscfirst_cub_m(void)
+{
+ return 0x3ff << 0;
+}
+static inline uint32_t gr2d_cscfirst_cub_v(uint32_t r)
+{
+ return (r >> 0) & 0x3ff;
+}
+static inline uint32_t gr2d_cscfirst_cvr_s(void)
+{
+ return 10;
+}
+static inline uint32_t gr2d_cscfirst_cvr_f(uint32_t v)
+{
+ return (v & 0x3ff) << 12;
+}
+static inline uint32_t gr2d_cscfirst_cvr_m(void)
+{
+ return 0x3ff << 12;
+}
+static inline uint32_t gr2d_cscfirst_cvr_v(uint32_t r)
+{
+ return (r >> 12) & 0x3ff;
+}
+static inline uint32_t gr2d_cscfirst_yos_s(void)
+{
+ return 8;
+}
+static inline uint32_t gr2d_cscfirst_yos_f(uint32_t v)
+{
+ return (v & 0xff) << 24;
+}
+static inline uint32_t gr2d_cscfirst_yos_m(void)
+{
+ return 0xff << 24;
+}
+static inline uint32_t gr2d_cscfirst_yos_v(uint32_t r)
+{
+ return (r >> 24) & 0xff;
+}
+static inline uint32_t gr2d_cscsecond_r(void)
+{
+ return 0x16;
+}
+static inline uint32_t gr2d_cscsecond_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_cscsecond_cug_s(void)
+{
+ return 9;
+}
+static inline uint32_t gr2d_cscsecond_cug_f(uint32_t v)
+{
+ return (v & 0x1ff) << 0;
+}
+static inline uint32_t gr2d_cscsecond_cug_m(void)
+{
+ return 0x1ff << 0;
+}
+static inline uint32_t gr2d_cscsecond_cug_v(uint32_t r)
+{
+ return (r >> 0) & 0x1ff;
+}
+static inline uint32_t gr2d_cscsecond_cur_s(void)
+{
+ return 10;
+}
+static inline uint32_t gr2d_cscsecond_cur_f(uint32_t v)
+{
+ return (v & 0x3ff) << 12;
+}
+static inline uint32_t gr2d_cscsecond_cur_m(void)
+{
+ return 0x3ff << 12;
+}
+static inline uint32_t gr2d_cscsecond_cur_v(uint32_t r)
+{
+ return (r >> 12) & 0x3ff;
+}
+static inline uint32_t gr2d_cscsecond_cyx_s(void)
+{
+ return 8;
+}
+static inline uint32_t gr2d_cscsecond_cyx_f(uint32_t v)
+{
+ return (v & 0xff) << 24;
+}
+static inline uint32_t gr2d_cscsecond_cyx_m(void)
+{
+ return 0xff << 24;
+}
+static inline uint32_t gr2d_cscsecond_cyx_v(uint32_t r)
+{
+ return (r >> 24) & 0xff;
+}
+static inline uint32_t gr2d_cscthird_r(void)
+{
+ return 0x17;
+}
+static inline uint32_t gr2d_cscthird_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_cscthird_cvg_s(void)
+{
+ return 9;
+}
+static inline uint32_t gr2d_cscthird_cvg_f(uint32_t v)
+{
+ return (v & 0x1ff) << 0;
+}
+static inline uint32_t gr2d_cscthird_cvg_m(void)
+{
+ return 0x1ff << 0;
+}
+static inline uint32_t gr2d_cscthird_cvg_v(uint32_t r)
+{
+ return (r >> 0) & 0x1ff;
+}
+static inline uint32_t gr2d_cscthird_cvb_s(void)
+{
+ return 10;
+}
+static inline uint32_t gr2d_cscthird_cvb_f(uint32_t v)
+{
+ return (v & 0x3ff) << 16;
+}
+static inline uint32_t gr2d_cscthird_cvb_m(void)
+{
+ return 0x3ff << 16;
+}
+static inline uint32_t gr2d_cscthird_cvb_v(uint32_t r)
+{
+ return (r >> 16) & 0x3ff;
+}
+static inline uint32_t gr2d_uba_r(void)
+{
+ return 0x1a;
+}
+static inline uint32_t gr2d_uba_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_uba_su1sa_s(void)
+{
+ return 32;
+}
+static inline uint32_t gr2d_uba_su1sa_f(uint32_t v)
+{
+ return (v & 0xffffffff) << 0;
+}
+static inline uint32_t gr2d_uba_su1sa_m(void)
+{
+ return 0xffffffff << 0;
+}
+static inline uint32_t gr2d_uba_su1sa_v(uint32_t r)
+{
+ return (r >> 0) & 0xffffffff;
+}
+static inline uint32_t gr2d_vba_r(void)
+{
+ return 0x1b;
+}
+static inline uint32_t gr2d_vba_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_vba_sv1sa_s(void)
+{
+ return 32;
+}
+static inline uint32_t gr2d_vba_sv1sa_f(uint32_t v)
+{
+ return (v & 0xffffffff) << 0;
+}
+static inline uint32_t gr2d_vba_sv1sa_m(void)
+{
+ return 0xffffffff << 0;
+}
+static inline uint32_t gr2d_vba_sv1sa_v(uint32_t r)
+{
+ return (r >> 0) & 0xffffffff;
+}
+static inline uint32_t gr2d_sbformat_r(void)
+{
+ return 0x1c;
+}
+static inline uint32_t gr2d_sbformat_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_sbformat_sifmt_s(void)
+{
+ return 5;
+}
+static inline uint32_t gr2d_sbformat_sifmt_f(uint32_t v)
+{
+ return (v & 0x1f) << 0;
+}
+static inline uint32_t gr2d_sbformat_sifmt_m(void)
+{
+ return 0x1f << 0;
+}
+static inline uint32_t gr2d_sbformat_sifmt_v(uint32_t r)
+{
+ return (r >> 0) & 0x1f;
+}
+static inline uint32_t gr2d_sbformat_sifmt_u8y8v8y8_ob_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_sbformat_sifmt_y8u8y8v8_ob_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_sbformat_sifmt_y8v8y8u8_ob_v(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_sbformat_sifmt_v8y8u8y8_ob_v(void)
+{
+ return 3;
+}
+static inline uint32_t gr2d_sbformat_sifmt_u8y8v8y8_tc_v(void)
+{
+ return 4;
+}
+static inline uint32_t gr2d_sbformat_sifmt_y8u8y8v8_tc_v(void)
+{
+ return 5;
+}
+static inline uint32_t gr2d_sbformat_sifmt_y8v8y8u8_tc_v(void)
+{
+ return 6;
+}
+static inline uint32_t gr2d_sbformat_sifmt_v8y8u8y8_tc_v(void)
+{
+ return 7;
+}
+static inline uint32_t gr2d_sbformat_sifmt_b5g6r5_v(void)
+{
+ return 8;
+}
+static inline uint32_t gr2d_sbformat_sifmt_b5g6r5bs_v(void)
+{
+ return 12;
+}
+static inline uint32_t gr2d_sbformat_sifmt_r8g8b8a8_v(void)
+{
+ return 14;
+}
+static inline uint32_t gr2d_sbformat_sifmt_b8g8r8a8_v(void)
+{
+ return 15;
+}
+static inline uint32_t gr2d_sbformat_difmt_s(void)
+{
+ return 5;
+}
+static inline uint32_t gr2d_sbformat_difmt_f(uint32_t v)
+{
+ return (v & 0x1f) << 8;
+}
+static inline uint32_t gr2d_sbformat_difmt_m(void)
+{
+ return 0x1f << 8;
+}
+static inline uint32_t gr2d_sbformat_difmt_v(uint32_t r)
+{
+ return (r >> 8) & 0x1f;
+}
+static inline uint32_t gr2d_sbformat_difmt_u8y8v8y8_ob_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_sbformat_difmt_y8u8y8v8_ob_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_sbformat_difmt_y8v8y8u8_ob_v(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_sbformat_difmt_v8y8u8y8_ob_v(void)
+{
+ return 3;
+}
+static inline uint32_t gr2d_sbformat_difmt_u8y8v8y8_tc_v(void)
+{
+ return 4;
+}
+static inline uint32_t gr2d_sbformat_difmt_y8u8y8v8_tc_v(void)
+{
+ return 5;
+}
+static inline uint32_t gr2d_sbformat_difmt_y8v8y8u8_tc_v(void)
+{
+ return 6;
+}
+static inline uint32_t gr2d_sbformat_difmt_v8y8u8y8_tc_v(void)
+{
+ return 7;
+}
+static inline uint32_t gr2d_sbformat_difmt_b5g6r5_v(void)
+{
+ return 8;
+}
+static inline uint32_t gr2d_sbformat_difmt_b5g6r5bs_v(void)
+{
+ return 12;
+}
+static inline uint32_t gr2d_sbformat_difmt_r8g8b8a8_v(void)
+{
+ return 14;
+}
+static inline uint32_t gr2d_sbformat_difmt_b8g8r8a8_v(void)
+{
+ return 15;
+}
+static inline uint32_t gr2d_controlsb_r(void)
+{
+ return 0x1d;
+}
+static inline uint32_t gr2d_controlsb_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_controlsb_imode_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_imode_f(uint32_t v)
+{
+ return (v & 0x1) << 5;
+}
+static inline uint32_t gr2d_controlsb_imode_m(void)
+{
+ return 0x1 << 5;
+}
+static inline uint32_t gr2d_controlsb_imode_v(uint32_t r)
+{
+ return (r >> 5) & 0x1;
+}
+static inline uint32_t gr2d_controlsb_imode_multiplex_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsb_imode_planar_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_enavf_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_enavf_f(uint32_t v)
+{
+ return (v & 0x1) << 6;
+}
+static inline uint32_t gr2d_controlsb_enavf_m(void)
+{
+ return 0x1 << 6;
+}
+static inline uint32_t gr2d_controlsb_enavf_v(uint32_t r)
+{
+ return (r >> 6) & 0x1;
+}
+static inline uint32_t gr2d_controlsb_enavf_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsb_enavf_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_enahf_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_enahf_f(uint32_t v)
+{
+ return (v & 0x1) << 7;
+}
+static inline uint32_t gr2d_controlsb_enahf_m(void)
+{
+ return 0x1 << 7;
+}
+static inline uint32_t gr2d_controlsb_enahf_v(uint32_t r)
+{
+ return (r >> 7) & 0x1;
+}
+static inline uint32_t gr2d_controlsb_enahf_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsb_enahf_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_uvst_s(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_controlsb_uvst_f(uint32_t v)
+{
+ return (v & 0x3) << 8;
+}
+static inline uint32_t gr2d_controlsb_uvst_m(void)
+{
+ return 0x3 << 8;
+}
+static inline uint32_t gr2d_controlsb_uvst_v(uint32_t r)
+{
+ return (r >> 8) & 0x3;
+}
+static inline uint32_t gr2d_controlsb_uvst_uvs2x_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsb_uvst_uvs1x_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_uvst_uvs4x_v(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_controlsb_uvst_uvs_g2uvstride_v(void)
+{
+ return 3;
+}
+static inline uint32_t gr2d_controlsb_vftype_s(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_controlsb_vftype_f(uint32_t v)
+{
+ return (v & 0x3) << 16;
+}
+static inline uint32_t gr2d_controlsb_vftype_m(void)
+{
+ return 0x3 << 16;
+}
+static inline uint32_t gr2d_controlsb_vftype_v(uint32_t r)
+{
+ return (r >> 16) & 0x3;
+}
+static inline uint32_t gr2d_controlsb_vftype_interp_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsb_vftype_avg25_interp75_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_vftype_avg50_interp50_v(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_controlsb_vftype_avg_v(void)
+{
+ return 3;
+}
+static inline uint32_t gr2d_controlsb_vfen_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_vfen_f(uint32_t v)
+{
+ return (v & 0x1) << 18;
+}
+static inline uint32_t gr2d_controlsb_vfen_m(void)
+{
+ return 0x1 << 18;
+}
+static inline uint32_t gr2d_controlsb_vfen_v(uint32_t r)
+{
+ return (r >> 18) & 0x1;
+}
+static inline uint32_t gr2d_controlsb_vfen_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsb_vfen_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_discsc_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_discsc_f(uint32_t v)
+{
+ return (v & 0x1) << 19;
+}
+static inline uint32_t gr2d_controlsb_discsc_m(void)
+{
+ return 0x1 << 19;
+}
+static inline uint32_t gr2d_controlsb_discsc_v(uint32_t r)
+{
+ return (r >> 19) & 0x1;
+}
+static inline uint32_t gr2d_controlsb_discsc_enable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsb_discsc_disable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_hftype_s(void)
+{
+ return 3;
+}
+static inline uint32_t gr2d_controlsb_hftype_f(uint32_t v)
+{
+ return (v & 0x7) << 20;
+}
+static inline uint32_t gr2d_controlsb_hftype_m(void)
+{
+ return 0x7 << 20;
+}
+static inline uint32_t gr2d_controlsb_hftype_v(uint32_t r)
+{
+ return (r >> 20) & 0x7;
+}
+static inline uint32_t gr2d_controlsb_hftype_interp_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsb_hftype_lpf1_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_hftype_lpf2_v(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_controlsb_hftype_lpf3_v(void)
+{
+ return 3;
+}
+static inline uint32_t gr2d_controlsb_hftype_lpf4_v(void)
+{
+ return 4;
+}
+static inline uint32_t gr2d_controlsb_hftype_lpf5_v(void)
+{
+ return 5;
+}
+static inline uint32_t gr2d_controlsb_hftype_lpf6_v(void)
+{
+ return 6;
+}
+static inline uint32_t gr2d_controlsb_hftype_disable_v(void)
+{
+ return 7;
+}
+static inline uint32_t gr2d_controlsb_rangeredfrm_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_rangeredfrm_f(uint32_t v)
+{
+ return (v & 0x1) << 23;
+}
+static inline uint32_t gr2d_controlsb_rangeredfrm_m(void)
+{
+ return 0x1 << 23;
+}
+static inline uint32_t gr2d_controlsb_rangeredfrm_v(uint32_t r)
+{
+ return (r >> 23) & 0x1;
+}
+static inline uint32_t gr2d_controlsb_rangeredfrm_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsb_rangeredfrm_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_sitype_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_sitype_f(uint32_t v)
+{
+ return (v & 0x1) << 24;
+}
+static inline uint32_t gr2d_controlsb_sitype_m(void)
+{
+ return 0x1 << 24;
+}
+static inline uint32_t gr2d_controlsb_sitype_v(uint32_t r)
+{
+ return (r >> 24) & 0x1;
+}
+static inline uint32_t gr2d_controlsb_sbsel_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_sbsel_f(uint32_t v)
+{
+ return (v & 0x1) << 25;
+}
+static inline uint32_t gr2d_controlsb_sbsel_m(void)
+{
+ return 0x1 << 25;
+}
+static inline uint32_t gr2d_controlsb_sbsel_v(uint32_t r)
+{
+ return (r >> 25) & 0x1;
+}
+static inline uint32_t gr2d_controlsb_sbsel_src_a_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsb_sbsel_src_b_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_dbsel_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_dbsel_f(uint32_t v)
+{
+ return (v & 0x1) << 26;
+}
+static inline uint32_t gr2d_controlsb_dbsel_m(void)
+{
+ return 0x1 << 26;
+}
+static inline uint32_t gr2d_controlsb_dbsel_v(uint32_t r)
+{
+ return (r >> 26) & 0x1;
+}
+static inline uint32_t gr2d_controlsb_dbsel_dst_a_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsb_dbsel_dst_b_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_keyen_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_keyen_f(uint32_t v)
+{
+ return (v & 0x1) << 27;
+}
+static inline uint32_t gr2d_controlsb_keyen_m(void)
+{
+ return 0x1 << 27;
+}
+static inline uint32_t gr2d_controlsb_keyen_v(uint32_t r)
+{
+ return (r >> 27) & 0x1;
+}
+static inline uint32_t gr2d_controlsb_keyen_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsb_keyen_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_kpol_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_kpol_f(uint32_t v)
+{
+ return (v & 0x1) << 28;
+}
+static inline uint32_t gr2d_controlsb_kpol_m(void)
+{
+ return 0x1 << 28;
+}
+static inline uint32_t gr2d_controlsb_kpol_v(uint32_t r)
+{
+ return (r >> 28) & 0x1;
+}
+static inline uint32_t gr2d_controlsb_kpol_within_bounds_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsb_kpol_outside_bounds_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_endith_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsb_endith_f(uint32_t v)
+{
+ return (v & 0x1) << 30;
+}
+static inline uint32_t gr2d_controlsb_endith_m(void)
+{
+ return 0x1 << 30;
+}
+static inline uint32_t gr2d_controlsb_endith_v(uint32_t r)
+{
+ return (r >> 30) & 0x1;
+}
+static inline uint32_t gr2d_controlsb_endith_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsb_endith_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsecond_r(void)
+{
+ return 0x1e;
+}
+static inline uint32_t gr2d_controlsecond_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_controlsecond_bitswap_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsecond_bitswap_f(uint32_t v)
+{
+ return (v & 0x1) << 1;
+}
+static inline uint32_t gr2d_controlsecond_bitswap_m(void)
+{
+ return 0x1 << 1;
+}
+static inline uint32_t gr2d_controlsecond_bitswap_v(uint32_t r)
+{
+ return (r >> 1) & 0x1;
+}
+static inline uint32_t gr2d_controlsecond_bitswap_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsecond_bitswap_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsecond_bebswap_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsecond_bebswap_f(uint32_t v)
+{
+ return (v & 0x1) << 2;
+}
+static inline uint32_t gr2d_controlsecond_bebswap_m(void)
+{
+ return 0x1 << 2;
+}
+static inline uint32_t gr2d_controlsecond_bebswap_v(uint32_t r)
+{
+ return (r >> 2) & 0x1;
+}
+static inline uint32_t gr2d_controlsecond_bebswap_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsecond_bebswap_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsecond_bewswap_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsecond_bewswap_f(uint32_t v)
+{
+ return (v & 0x1) << 3;
+}
+static inline uint32_t gr2d_controlsecond_bewswap_m(void)
+{
+ return 0x1 << 3;
+}
+static inline uint32_t gr2d_controlsecond_bewswap_v(uint32_t r)
+{
+ return (r >> 3) & 0x1;
+}
+static inline uint32_t gr2d_controlsecond_bewswap_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsecond_bewswap_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsecond_alptype_s(void)
+{
+ return 5;
+}
+static inline uint32_t gr2d_controlsecond_alptype_f(uint32_t v)
+{
+ return (v & 0x1f) << 4;
+}
+static inline uint32_t gr2d_controlsecond_alptype_m(void)
+{
+ return 0x1f << 4;
+}
+static inline uint32_t gr2d_controlsecond_alptype_v(uint32_t r)
+{
+ return (r >> 4) & 0x1f;
+}
+static inline uint32_t gr2d_controlsecond_alptype_fix_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsecond_alptype_pl1bpp_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsecond_alptype_pl2bpp_v(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_controlsecond_alptype_pl4bpp_v(void)
+{
+ return 3;
+}
+static inline uint32_t gr2d_controlsecond_alptype_pl8bpp_v(void)
+{
+ return 4;
+}
+static inline uint32_t gr2d_controlsecond_alptype_pl44bpp_v(void)
+{
+ return 5;
+}
+static inline uint32_t gr2d_controlsecond_alptype_pls1bpp_v(void)
+{
+ return 6;
+}
+static inline uint32_t gr2d_controlsecond_alptype_pls4bppal_v(void)
+{
+ return 7;
+}
+static inline uint32_t gr2d_controlsecond_alptype_pls4bpp_v(void)
+{
+ return 8;
+}
+static inline uint32_t gr2d_controlsecond_alptype_pls8bpp_v(void)
+{
+ return 9;
+}
+static inline uint32_t gr2d_controlsecond_alptype_pls8bx_v(void)
+{
+ return 10;
+}
+static inline uint32_t gr2d_controlsecond_alptype_pls1bppal_v(void)
+{
+ return 11;
+}
+static inline uint32_t gr2d_controlsecond_alpsrcordst_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsecond_alpsrcordst_f(uint32_t v)
+{
+ return (v & 0x1) << 9;
+}
+static inline uint32_t gr2d_controlsecond_alpsrcordst_m(void)
+{
+ return 0x1 << 9;
+}
+static inline uint32_t gr2d_controlsecond_alpsrcordst_v(uint32_t r)
+{
+ return (r >> 9) & 0x1;
+}
+static inline uint32_t gr2d_controlsecond_alpsrcordst_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsecond_alpsrcordst_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsecond_clipc_s(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_controlsecond_clipc_f(uint32_t v)
+{
+ return (v & 0x3) << 21;
+}
+static inline uint32_t gr2d_controlsecond_clipc_m(void)
+{
+ return 0x3 << 21;
+}
+static inline uint32_t gr2d_controlsecond_clipc_v(uint32_t r)
+{
+ return (r >> 21) & 0x3;
+}
+static inline uint32_t gr2d_controlsecond_fr_mode_s(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_controlsecond_fr_mode_f(uint32_t v)
+{
+ return (v & 0x3) << 24;
+}
+static inline uint32_t gr2d_controlsecond_fr_mode_m(void)
+{
+ return 0x3 << 24;
+}
+static inline uint32_t gr2d_controlsecond_fr_mode_v(uint32_t r)
+{
+ return (r >> 24) & 0x3;
+}
+static inline uint32_t gr2d_controlsecond_fr_mode_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsecond_fr_mode_src_dst_copy_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsecond_fr_mode_square_v(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_controlsecond_fr_mode_blank_v(void)
+{
+ return 3;
+}
+static inline uint32_t gr2d_controlsecond_fr_type_s(void)
+{
+ return 3;
+}
+static inline uint32_t gr2d_controlsecond_fr_type_f(uint32_t v)
+{
+ return (v & 0x7) << 26;
+}
+static inline uint32_t gr2d_controlsecond_fr_type_m(void)
+{
+ return 0x7 << 26;
+}
+static inline uint32_t gr2d_controlsecond_fr_type_v(uint32_t r)
+{
+ return (r >> 26) & 0x7;
+}
+static inline uint32_t gr2d_controlsecond_fr_type_flip_x_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsecond_fr_type_flip_y_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsecond_fr_type_trans_lr_v(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_controlsecond_fr_type_trans_rl_v(void)
+{
+ return 3;
+}
+static inline uint32_t gr2d_controlsecond_fr_type_rot_90_v(void)
+{
+ return 4;
+}
+static inline uint32_t gr2d_controlsecond_fr_type_rot_180_v(void)
+{
+ return 5;
+}
+static inline uint32_t gr2d_controlsecond_fr_type_rot_270_v(void)
+{
+ return 6;
+}
+static inline uint32_t gr2d_controlsecond_fr_type_identity_v(void)
+{
+ return 7;
+}
+static inline uint32_t gr2d_controlsecond_fr_readwait_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlsecond_fr_readwait_f(uint32_t v)
+{
+ return (v & 0x1) << 29;
+}
+static inline uint32_t gr2d_controlsecond_fr_readwait_m(void)
+{
+ return 0x1 << 29;
+}
+static inline uint32_t gr2d_controlsecond_fr_readwait_v(uint32_t r)
+{
+ return (r >> 29) & 0x1;
+}
+static inline uint32_t gr2d_controlsecond_fr_readwait_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlsecond_fr_readwait_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_r(void)
+{
+ return 0x1f;
+}
+static inline uint32_t gr2d_controlmain_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_controlmain_cmdt_s(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_controlmain_cmdt_f(uint32_t v)
+{
+ return (v & 0x3) << 0;
+}
+static inline uint32_t gr2d_controlmain_cmdt_m(void)
+{
+ return 0x3 << 0;
+}
+static inline uint32_t gr2d_controlmain_cmdt_v(uint32_t r)
+{
+ return (r >> 0) & 0x3;
+}
+static inline uint32_t gr2d_controlmain_cmdt_bitblt_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlmain_cmdt_linedraw_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_cmdt_vcaa_v(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_controlmain_cmdt_reserved1_v(void)
+{
+ return 3;
+}
+static inline uint32_t gr2d_controlmain_turbofill_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_turbofill_f(uint32_t v)
+{
+ return (v & 0x1) << 2;
+}
+static inline uint32_t gr2d_controlmain_turbofill_m(void)
+{
+ return 0x1 << 2;
+}
+static inline uint32_t gr2d_controlmain_turbofill_v(uint32_t r)
+{
+ return (r >> 2) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_test0bit_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_test0bit_f(uint32_t v)
+{
+ return (v & 0x1) << 3;
+}
+static inline uint32_t gr2d_controlmain_test0bit_m(void)
+{
+ return 0x1 << 3;
+}
+static inline uint32_t gr2d_controlmain_test0bit_v(uint32_t r)
+{
+ return (r >> 3) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_test0bit_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlmain_test0bit_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_faden_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_faden_f(uint32_t v)
+{
+ return (v & 0x1) << 4;
+}
+static inline uint32_t gr2d_controlmain_faden_m(void)
+{
+ return 0x1 << 4;
+}
+static inline uint32_t gr2d_controlmain_faden_v(uint32_t r)
+{
+ return (r >> 4) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_faden_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlmain_faden_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_alpen_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_alpen_f(uint32_t v)
+{
+ return (v & 0x1) << 5;
+}
+static inline uint32_t gr2d_controlmain_alpen_m(void)
+{
+ return 0x1 << 5;
+}
+static inline uint32_t gr2d_controlmain_alpen_v(uint32_t r)
+{
+ return (r >> 5) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_srcsld_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_srcsld_f(uint32_t v)
+{
+ return (v & 0x1) << 6;
+}
+static inline uint32_t gr2d_controlmain_srcsld_m(void)
+{
+ return 0x1 << 6;
+}
+static inline uint32_t gr2d_controlmain_srcsld_v(uint32_t r)
+{
+ return (r >> 6) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_srcsld_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlmain_srcsld_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_patsld_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_patsld_f(uint32_t v)
+{
+ return (v & 0x1) << 7;
+}
+static inline uint32_t gr2d_controlmain_patsld_m(void)
+{
+ return 0x1 << 7;
+}
+static inline uint32_t gr2d_controlmain_patsld_v(uint32_t r)
+{
+ return (r >> 7) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_patsld_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlmain_patsld_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_patfl_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_patfl_f(uint32_t v)
+{
+ return (v & 0x1) << 8;
+}
+static inline uint32_t gr2d_controlmain_patfl_m(void)
+{
+ return 0x1 << 8;
+}
+static inline uint32_t gr2d_controlmain_patfl_v(uint32_t r)
+{
+ return (r >> 8) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_patfl_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlmain_patfl_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_xdir_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_xdir_f(uint32_t v)
+{
+ return (v & 0x1) << 9;
+}
+static inline uint32_t gr2d_controlmain_xdir_m(void)
+{
+ return 0x1 << 9;
+}
+static inline uint32_t gr2d_controlmain_xdir_v(uint32_t r)
+{
+ return (r >> 9) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_ydir_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_ydir_f(uint32_t v)
+{
+ return (v & 0x1) << 10;
+}
+static inline uint32_t gr2d_controlmain_ydir_m(void)
+{
+ return 0x1 << 10;
+}
+static inline uint32_t gr2d_controlmain_ydir_v(uint32_t r)
+{
+ return (r >> 10) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_xytdw_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_xytdw_f(uint32_t v)
+{
+ return (v & 0x1) << 11;
+}
+static inline uint32_t gr2d_controlmain_xytdw_m(void)
+{
+ return 0x1 << 11;
+}
+static inline uint32_t gr2d_controlmain_xytdw_v(uint32_t r)
+{
+ return (r >> 11) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_srcpack_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_srcpack_f(uint32_t v)
+{
+ return (v & 0x1) << 12;
+}
+static inline uint32_t gr2d_controlmain_srcpack_m(void)
+{
+ return 0x1 << 12;
+}
+static inline uint32_t gr2d_controlmain_srcpack_v(uint32_t r)
+{
+ return (r >> 12) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_srcpack_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlmain_srcpack_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_patpack_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_patpack_f(uint32_t v)
+{
+ return (v & 0x1) << 13;
+}
+static inline uint32_t gr2d_controlmain_patpack_m(void)
+{
+ return 0x1 << 13;
+}
+static inline uint32_t gr2d_controlmain_patpack_v(uint32_t r)
+{
+ return (r >> 13) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_patpack_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlmain_patpack_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_yflip_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_yflip_f(uint32_t v)
+{
+ return (v & 0x1) << 14;
+}
+static inline uint32_t gr2d_controlmain_yflip_m(void)
+{
+ return 0x1 << 14;
+}
+static inline uint32_t gr2d_controlmain_yflip_v(uint32_t r)
+{
+ return (r >> 14) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_yflip_dsiable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlmain_yflip_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_srcsel_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_srcsel_f(uint32_t v)
+{
+ return (v & 0x1) << 15;
+}
+static inline uint32_t gr2d_controlmain_srcsel_m(void)
+{
+ return 0x1 << 15;
+}
+static inline uint32_t gr2d_controlmain_srcsel_v(uint32_t r)
+{
+ return (r >> 15) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_srcsel_screen_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlmain_srcsel_memory_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_dstcd_s(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_controlmain_dstcd_f(uint32_t v)
+{
+ return (v & 0x3) << 16;
+}
+static inline uint32_t gr2d_controlmain_dstcd_m(void)
+{
+ return 0x3 << 16;
+}
+static inline uint32_t gr2d_controlmain_dstcd_v(uint32_t r)
+{
+ return (r >> 16) & 0x3;
+}
+static inline uint32_t gr2d_controlmain_dstcd_bpp8_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlmain_dstcd_bpp16_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_dstcd_bpp32_v(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_controlmain_dstcd_reserved3_v(void)
+{
+ return 3;
+}
+static inline uint32_t gr2d_controlmain_dstt_s(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_controlmain_dstt_f(uint32_t v)
+{
+ return (v & 0x3) << 18;
+}
+static inline uint32_t gr2d_controlmain_dstt_m(void)
+{
+ return 0x3 << 18;
+}
+static inline uint32_t gr2d_controlmain_dstt_v(uint32_t r)
+{
+ return (r >> 18) & 0x3;
+}
+static inline uint32_t gr2d_controlmain_srccd_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_srccd_f(uint32_t v)
+{
+ return (v & 0x1) << 20;
+}
+static inline uint32_t gr2d_controlmain_srccd_m(void)
+{
+ return 0x1 << 20;
+}
+static inline uint32_t gr2d_controlmain_srccd_v(uint32_t r)
+{
+ return (r >> 20) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_hlmono_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_hlmono_f(uint32_t v)
+{
+ return (v & 0x1) << 21;
+}
+static inline uint32_t gr2d_controlmain_hlmono_m(void)
+{
+ return 0x1 << 21;
+}
+static inline uint32_t gr2d_controlmain_hlmono_v(uint32_t r)
+{
+ return (r >> 21) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_srct_s(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_controlmain_srct_f(uint32_t v)
+{
+ return (v & 0x3) << 22;
+}
+static inline uint32_t gr2d_controlmain_srct_m(void)
+{
+ return 0x3 << 22;
+}
+static inline uint32_t gr2d_controlmain_srct_v(uint32_t r)
+{
+ return (r >> 22) & 0x3;
+}
+static inline uint32_t gr2d_controlmain_srcbas_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_srcbas_f(uint32_t v)
+{
+ return (v & 0x1) << 24;
+}
+static inline uint32_t gr2d_controlmain_srcbas_m(void)
+{
+ return 0x1 << 24;
+}
+static inline uint32_t gr2d_controlmain_srcbas_v(uint32_t r)
+{
+ return (r >> 24) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_gcsw_s(void)
+{
+ return 2;
+}
+static inline uint32_t gr2d_controlmain_gcsw_f(uint32_t v)
+{
+ return (v & 0x3) << 25;
+}
+static inline uint32_t gr2d_controlmain_gcsw_m(void)
+{
+ return 0x3 << 25;
+}
+static inline uint32_t gr2d_controlmain_gcsw_v(uint32_t r)
+{
+ return (r >> 25) & 0x3;
+}
+static inline uint32_t gr2d_controlmain_srcdir_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_srcdir_f(uint32_t v)
+{
+ return (v & 0x1) << 27;
+}
+static inline uint32_t gr2d_controlmain_srcdir_m(void)
+{
+ return 0x1 << 27;
+}
+static inline uint32_t gr2d_controlmain_srcdir_v(uint32_t r)
+{
+ return (r >> 27) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_dstdir_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_dstdir_f(uint32_t v)
+{
+ return (v & 0x1) << 28;
+}
+static inline uint32_t gr2d_controlmain_dstdir_m(void)
+{
+ return 0x1 << 28;
+}
+static inline uint32_t gr2d_controlmain_dstdir_v(uint32_t r)
+{
+ return (r >> 28) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_patsel_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_patsel_f(uint32_t v)
+{
+ return (v & 0x1) << 30;
+}
+static inline uint32_t gr2d_controlmain_patsel_m(void)
+{
+ return 0x1 << 30;
+}
+static inline uint32_t gr2d_controlmain_patsel_v(uint32_t r)
+{
+ return (r >> 30) & 0x1;
+}
+static inline uint32_t gr2d_controlmain_patsel_screen_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlmain_patsel_memory_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_ropfade_r(void)
+{
+ return 0x20;
+}
+static inline uint32_t gr2d_ropfade_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_ropfade_rop_s(void)
+{
+ return 8;
+}
+static inline uint32_t gr2d_ropfade_rop_f(uint32_t v)
+{
+ return (v & 0xff) << 0;
+}
+static inline uint32_t gr2d_ropfade_rop_m(void)
+{
+ return 0xff << 0;
+}
+static inline uint32_t gr2d_ropfade_rop_v(uint32_t r)
+{
+ return (r >> 0) & 0xff;
+}
+static inline uint32_t gr2d_ropfade_fadcoe_s(void)
+{
+ return 8;
+}
+static inline uint32_t gr2d_ropfade_fadcoe_f(uint32_t v)
+{
+ return (v & 0xff) << 16;
+}
+static inline uint32_t gr2d_ropfade_fadcoe_m(void)
+{
+ return 0xff << 16;
+}
+static inline uint32_t gr2d_ropfade_fadcoe_v(uint32_t r)
+{
+ return (r >> 16) & 0xff;
+}
+static inline uint32_t gr2d_ropfade_fadoff_s(void)
+{
+ return 8;
+}
+static inline uint32_t gr2d_ropfade_fadoff_f(uint32_t v)
+{
+ return (v & 0xff) << 24;
+}
+static inline uint32_t gr2d_ropfade_fadoff_m(void)
+{
+ return 0xff << 24;
+}
+static inline uint32_t gr2d_ropfade_fadoff_v(uint32_t r)
+{
+ return (r >> 24) & 0xff;
+}
+static inline uint32_t gr2d_dstba_r(void)
+{
+ return 0x2b;
+}
+static inline uint32_t gr2d_dstba_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_dstba_dstba_s(void)
+{
+ return 32;
+}
+static inline uint32_t gr2d_dstba_dstba_f(uint32_t v)
+{
+ return (v & 0xffffffff) << 0;
+}
+static inline uint32_t gr2d_dstba_dstba_m(void)
+{
+ return 0xffffffff << 0;
+}
+static inline uint32_t gr2d_dstba_dstba_v(uint32_t r)
+{
+ return (r >> 0) & 0xffffffff;
+}
+static inline uint32_t gr2d_dstst_r(void)
+{
+ return 0x2e;
+}
+static inline uint32_t gr2d_dstst_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_dstst_dsts_s(void)
+{
+ return 16;
+}
+static inline uint32_t gr2d_dstst_dsts_f(uint32_t v)
+{
+ return (v & 0xffff) << 0;
+}
+static inline uint32_t gr2d_dstst_dsts_m(void)
+{
+ return 0xffff << 0;
+}
+static inline uint32_t gr2d_dstst_dsts_v(uint32_t r)
+{
+ return (r >> 0) & 0xffff;
+}
+static inline uint32_t gr2d_srcba_r(void)
+{
+ return 0x31;
+}
+static inline uint32_t gr2d_srcba_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_srcba_srcba_s(void)
+{
+ return 32;
+}
+static inline uint32_t gr2d_srcba_srcba_f(uint32_t v)
+{
+ return (v & 0xffffffff) << 0;
+}
+static inline uint32_t gr2d_srcba_srcba_m(void)
+{
+ return 0xffffffff << 0;
+}
+static inline uint32_t gr2d_srcba_srcba_v(uint32_t r)
+{
+ return (r >> 0) & 0xffffffff;
+}
+static inline uint32_t gr2d_srcst_r(void)
+{
+ return 0x33;
+}
+static inline uint32_t gr2d_srcst_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_srcst_srcs_s(void)
+{
+ return 16;
+}
+static inline uint32_t gr2d_srcst_srcs_f(uint32_t v)
+{
+ return (v & 0xffff) << 0;
+}
+static inline uint32_t gr2d_srcst_srcs_m(void)
+{
+ return 0xffff << 0;
+}
+static inline uint32_t gr2d_srcst_srcs_v(uint32_t r)
+{
+ return (r >> 0) & 0xffff;
+}
+static inline uint32_t gr2d_srcfgc_r(void)
+{
+ return 0x35;
+}
+static inline uint32_t gr2d_srcfgc_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_srcfgc_srcfgc_s(void)
+{
+ return 32;
+}
+static inline uint32_t gr2d_srcfgc_srcfgc_f(uint32_t v)
+{
+ return (v & 0xffffffff) << 0;
+}
+static inline uint32_t gr2d_srcfgc_srcfgc_m(void)
+{
+ return 0xffffffff << 0;
+}
+static inline uint32_t gr2d_srcfgc_srcfgc_v(uint32_t r)
+{
+ return (r >> 0) & 0xffffffff;
+}
+static inline uint32_t gr2d_srcsize_r(void)
+{
+ return 0x37;
+}
+static inline uint32_t gr2d_srcsize_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_srcsize_srcwidth_s(void)
+{
+ return 15;
+}
+static inline uint32_t gr2d_srcsize_srcwidth_f(uint32_t v)
+{
+ return (v & 0x7fff) << 0;
+}
+static inline uint32_t gr2d_srcsize_srcwidth_m(void)
+{
+ return 0x7fff << 0;
+}
+static inline uint32_t gr2d_srcsize_srcwidth_v(uint32_t r)
+{
+ return (r >> 0) & 0x7fff;
+}
+static inline uint32_t gr2d_srcsize_srcheight_s(void)
+{
+ return 15;
+}
+static inline uint32_t gr2d_srcsize_srcheight_f(uint32_t v)
+{
+ return (v & 0x7fff) << 16;
+}
+static inline uint32_t gr2d_srcsize_srcheight_m(void)
+{
+ return 0x7fff << 16;
+}
+static inline uint32_t gr2d_srcsize_srcheight_v(uint32_t r)
+{
+ return (r >> 16) & 0x7fff;
+}
+static inline uint32_t gr2d_dstsize_r(void)
+{
+ return 0x38;
+}
+static inline uint32_t gr2d_dstsize_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_dstsize_dstwidth_s(void)
+{
+ return 15;
+}
+static inline uint32_t gr2d_dstsize_dstwidth_f(uint32_t v)
+{
+ return (v & 0x7fff) << 0;
+}
+static inline uint32_t gr2d_dstsize_dstwidth_m(void)
+{
+ return 0x7fff << 0;
+}
+static inline uint32_t gr2d_dstsize_dstwidth_v(uint32_t r)
+{
+ return (r >> 0) & 0x7fff;
+}
+static inline uint32_t gr2d_dstsize_dstheight_s(void)
+{
+ return 15;
+}
+static inline uint32_t gr2d_dstsize_dstheight_f(uint32_t v)
+{
+ return (v & 0x7fff) << 16;
+}
+static inline uint32_t gr2d_dstsize_dstheight_m(void)
+{
+ return 0x7fff << 16;
+}
+static inline uint32_t gr2d_dstsize_dstheight_v(uint32_t r)
+{
+ return (r >> 16) & 0x7fff;
+}
+static inline uint32_t gr2d_srcps_r(void)
+{
+ return 0x39;
+}
+static inline uint32_t gr2d_srcps_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_srcps_srcx_s(void)
+{
+ return 16;
+}
+static inline uint32_t gr2d_srcps_srcx_f(uint32_t v)
+{
+ return (v & 0xffff) << 0;
+}
+static inline uint32_t gr2d_srcps_srcx_m(void)
+{
+ return 0xffff << 0;
+}
+static inline uint32_t gr2d_srcps_srcx_v(uint32_t r)
+{
+ return (r >> 0) & 0xffff;
+}
+static inline uint32_t gr2d_srcps_srcy_s(void)
+{
+ return 16;
+}
+static inline uint32_t gr2d_srcps_srcy_f(uint32_t v)
+{
+ return (v & 0xffff) << 16;
+}
+static inline uint32_t gr2d_srcps_srcy_m(void)
+{
+ return 0xffff << 16;
+}
+static inline uint32_t gr2d_srcps_srcy_v(uint32_t r)
+{
+ return (r >> 16) & 0xffff;
+}
+static inline uint32_t gr2d_dstps_r(void)
+{
+ return 0x3a;
+}
+static inline uint32_t gr2d_dstps_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_dstps_dstx_s(void)
+{
+ return 16;
+}
+static inline uint32_t gr2d_dstps_dstx_f(uint32_t v)
+{
+ return (v & 0xffff) << 0;
+}
+static inline uint32_t gr2d_dstps_dstx_m(void)
+{
+ return 0xffff << 0;
+}
+static inline uint32_t gr2d_dstps_dstx_v(uint32_t r)
+{
+ return (r >> 0) & 0xffff;
+}
+static inline uint32_t gr2d_dstps_dsty_s(void)
+{
+ return 16;
+}
+static inline uint32_t gr2d_dstps_dsty_f(uint32_t v)
+{
+ return (v & 0xffff) << 16;
+}
+static inline uint32_t gr2d_dstps_dsty_m(void)
+{
+ return 0xffff << 16;
+}
+static inline uint32_t gr2d_dstps_dsty_v(uint32_t r)
+{
+ return (r >> 16) & 0xffff;
+}
+static inline uint32_t gr2d_uvstride_r(void)
+{
+ return 0x44;
+}
+static inline uint32_t gr2d_uvstride_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_uvstride_uvstride_s(void)
+{
+ return 16;
+}
+static inline uint32_t gr2d_uvstride_uvstride_f(uint32_t v)
+{
+ return (v & 0xffff) << 0;
+}
+static inline uint32_t gr2d_uvstride_uvstride_m(void)
+{
+ return 0xffff << 0;
+}
+static inline uint32_t gr2d_uvstride_uvstride_v(uint32_t r)
+{
+ return (r >> 0) & 0xffff;
+}
+static inline uint32_t gr2d_tilemode_r(void)
+{
+ return 0x46;
+}
+static inline uint32_t gr2d_tilemode_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_tilemode_src_y_tile_mode_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_tilemode_src_y_tile_mode_f(uint32_t v)
+{
+ return (v & 0x1) << 0;
+}
+static inline uint32_t gr2d_tilemode_src_y_tile_mode_m(void)
+{
+ return 0x1 << 0;
+}
+static inline uint32_t gr2d_tilemode_src_y_tile_mode_v(uint32_t r)
+{
+ return (r >> 0) & 0x1;
+}
+static inline uint32_t gr2d_tilemode_src_y_tile_mode_linear_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_tilemode_src_y_tile_mode_tiled_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_tilemode_src_uv_tile_mode_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_tilemode_src_uv_tile_mode_f(uint32_t v)
+{
+ return (v & 0x1) << 4;
+}
+static inline uint32_t gr2d_tilemode_src_uv_tile_mode_m(void)
+{
+ return 0x1 << 4;
+}
+static inline uint32_t gr2d_tilemode_src_uv_tile_mode_v(uint32_t r)
+{
+ return (r >> 4) & 0x1;
+}
+static inline uint32_t gr2d_tilemode_src_uv_tile_mode_linear_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_tilemode_src_uv_tile_mode_tiled_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_tilemode_pat_y_tile_mode_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_tilemode_pat_y_tile_mode_f(uint32_t v)
+{
+ return (v & 0x1) << 8;
+}
+static inline uint32_t gr2d_tilemode_pat_y_tile_mode_m(void)
+{
+ return 0x1 << 8;
+}
+static inline uint32_t gr2d_tilemode_pat_y_tile_mode_v(uint32_t r)
+{
+ return (r >> 8) & 0x1;
+}
+static inline uint32_t gr2d_tilemode_pat_y_tile_mode_linear_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_tilemode_pat_y_tile_mode_tiled_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_tilemode_pat_uv_tile_mode_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_tilemode_pat_uv_tile_mode_f(uint32_t v)
+{
+ return (v & 0x1) << 12;
+}
+static inline uint32_t gr2d_tilemode_pat_uv_tile_mode_m(void)
+{
+ return 0x1 << 12;
+}
+static inline uint32_t gr2d_tilemode_pat_uv_tile_mode_v(uint32_t r)
+{
+ return (r >> 12) & 0x1;
+}
+static inline uint32_t gr2d_tilemode_pat_uv_tile_mode_linear_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_tilemode_pat_uv_tile_mode_tiled_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_tilemode_dst_rd_tile_mode_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_tilemode_dst_rd_tile_mode_f(uint32_t v)
+{
+ return (v & 0x1) << 16;
+}
+static inline uint32_t gr2d_tilemode_dst_rd_tile_mode_m(void)
+{
+ return 0x1 << 16;
+}
+static inline uint32_t gr2d_tilemode_dst_rd_tile_mode_v(uint32_t r)
+{
+ return (r >> 16) & 0x1;
+}
+static inline uint32_t gr2d_tilemode_dst_rd_tile_mode_linear_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_tilemode_dst_rd_tile_mode_tiled_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_tilemode_dst_wr_tile_mode_s(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_tilemode_dst_wr_tile_mode_f(uint32_t v)
+{
+ return (v & 0x1) << 20;
+}
+static inline uint32_t gr2d_tilemode_dst_wr_tile_mode_m(void)
+{
+ return 0x1 << 20;
+}
+static inline uint32_t gr2d_tilemode_dst_wr_tile_mode_v(uint32_t r)
+{
+ return (r >> 20) & 0x1;
+}
+static inline uint32_t gr2d_tilemode_dst_wr_tile_mode_linear_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_tilemode_dst_wr_tile_mode_tiled_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_srcba_sb_surfbase_r(void)
+{
+ return 0x48;
+}
+static inline uint32_t gr2d_srcba_sb_surfbase_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_srcba_sb_surfbase_src_addr_s(void)
+{
+ return 32;
+}
+static inline uint32_t gr2d_srcba_sb_surfbase_src_addr_f(uint32_t v)
+{
+ return (v & 0xffffffff) << 0;
+}
+static inline uint32_t gr2d_srcba_sb_surfbase_src_addr_m(void)
+{
+ return 0xffffffff << 0;
+}
+static inline uint32_t gr2d_srcba_sb_surfbase_src_addr_v(uint32_t r)
+{
+ return (r >> 0) & 0xffffffff;
+}
+static inline uint32_t gr2d_dstba_sb_surfbase_r(void)
+{
+ return 0x49;
+}
+static inline uint32_t gr2d_dstba_sb_surfbase_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_dstba_sb_surfbase_dst_addr_s(void)
+{
+ return 32;
+}
+static inline uint32_t gr2d_dstba_sb_surfbase_dst_addr_f(uint32_t v)
+{
+ return (v & 0xffffffff) << 0;
+}
+static inline uint32_t gr2d_dstba_sb_surfbase_dst_addr_m(void)
+{
+ return 0xffffffff << 0;
+}
+static inline uint32_t gr2d_dstba_sb_surfbase_dst_addr_v(uint32_t r)
+{
+ return (r >> 0) & 0xffffffff;
+}
+static inline uint32_t gr2d_vba_sb_surfbase_r(void)
+{
+ return 0x4b;
+}
+static inline uint32_t gr2d_vba_sb_surfbase_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_vba_sb_surfbase_v_addr_s(void)
+{
+ return 32;
+}
+static inline uint32_t gr2d_vba_sb_surfbase_v_addr_f(uint32_t v)
+{
+ return (v & 0xffffffff) << 0;
+}
+static inline uint32_t gr2d_vba_sb_surfbase_v_addr_m(void)
+{
+ return 0xffffffff << 0;
+}
+static inline uint32_t gr2d_vba_sb_surfbase_v_addr_v(uint32_t r)
+{
+ return (r >> 0) & 0xffffffff;
+}
+static inline uint32_t gr2d_uba_sb_surfbase_r(void)
+{
+ return 0x4c;
+}
+static inline uint32_t gr2d_uba_sb_surfbase_reset_val_v(void)
+{
+ return 0x0;
+}
+static inline uint32_t gr2d_uba_sb_surfbase_u_addr_s(void)
+{
+ return 32;
+}
+static inline uint32_t gr2d_uba_sb_surfbase_u_addr_f(uint32_t v)
+{
+ return (v & 0xffffffff) << 0;
+}
+static inline uint32_t gr2d_uba_sb_surfbase_u_addr_m(void)
+{
+ return 0xffffffff << 0;
+}
+static inline uint32_t gr2d_uba_sb_surfbase_u_addr_v(uint32_t r)
+{
+ return (r >> 0) & 0xffffffff;
+}
+
+#endif /* __hw_gr2d_h__ */
diff --git a/tegra/2d/tegra_2d_api.c b/tegra/2d/tegra_2d_api.c
new file mode 100644
index 0000000..a4b5101
--- /dev/null
+++ b/tegra/2d/tegra_2d_api.c
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#include <stdlib.h>
+#include "tegra_2d.h"
+#include "tegra_2d_context.h"
+#include "tegra_2d_copy.h"
+#include "tegra_2d_fill.h"
+#include "tegra_2d_color.h"
+#include "tegra_2d_surface.h"
+#include "tegra_2d_util.h"
+
+#define ENTER() \
+ if (ctx->log_enable) LOG("> %s\n", __func__)
+
+#define RETURN(x) \
+ if (ctx->log_enable) \
+ LOG("- %s: %s\n", __func__, result_to_str((enum tegra_2d_result) x)); \
+ return x
+
+#define RETURN_VOID() \
+ if (ctx->log_enable) \
+ LOG("- %s\n", __func__); \
+ return
+
+struct tegra_2d_context *
+tegra_2d_open(int fd)
+{
+ struct tegra_2d_ictx *ictx;
+
+ ictx = open2d(fd);
+
+ return (struct tegra_2d_context *) ictx;
+}
+
+void
+tegra_2d_close(struct tegra_2d_context *ctx)
+{
+ struct tegra_2d_ictx *ictx = (struct tegra_2d_ictx *) ctx;
+
+ if (ctx == NULL)
+ return;
+
+ ENTER();
+
+ close2d(ictx);
+}
+
+int
+tegra_2d_begin(struct tegra_2d_context *ctx,
+ const struct tegra_fence *fence)
+{
+ int result;
+ struct tegra_2d_ictx *ictx = (struct tegra_2d_ictx *) ctx;
+
+ if (ctx == NULL)
+ return TEGRA_2D_INVALID_PARAMETER;
+
+ ENTER();
+
+ result = begin2d(ictx, fence);
+
+ RETURN(result);
+}
+
+int
+tegra_2d_end(struct tegra_2d_context *ctx,
+ struct tegra_fence *fence)
+{
+ int result;
+ struct tegra_2d_ictx *ictx = (struct tegra_2d_ictx *) ctx;
+
+ if (ctx == NULL)
+ return TEGRA_2D_INVALID_PARAMETER;
+
+ ENTER();
+
+ result = end2d(ictx, fence);
+
+ RETURN(result);
+}
+
+int
+tegra_2d_fill(struct tegra_2d_context *ctx,
+ const struct tegra_2d_surface *dst,
+ const struct tegra_2d_surface_color *color,
+ const struct tegra_2d_rect *dst_rect)
+{
+ int result;
+ struct tegra_2d_ictx *ictx = (struct tegra_2d_ictx *) ctx;
+
+ if (ctx == NULL)
+ return TEGRA_2D_INVALID_PARAMETER;
+
+ ENTER();
+
+ result = fill2d(ictx, dst, color, dst_rect);
+
+ RETURN(result);
+}
+
+int
+tegra_2d_copy(struct tegra_2d_context *ctx,
+ const struct tegra_2d_surface *dst,
+ const struct tegra_2d_surface *src,
+ const struct tegra_2d_rect *dst_rect,
+ const struct tegra_2d_rect *src_rect,
+ enum tegra_2d_transform transform)
+{
+ int result;
+ struct tegra_2d_ictx *ictx = (struct tegra_2d_ictx *) ctx;
+
+ if (ctx == NULL)
+ return TEGRA_2D_INVALID_PARAMETER;
+
+ ENTER();
+
+ result = copy2d(ictx, dst, src, dst_rect, src_rect, transform);
+
+ RETURN(result);
+}
+
+int
+tegra_2d_compute_requirements(const struct tegra_2d_plane *plane,
+ uint32_t *num_bytes,
+ uint32_t *alignment,
+ uint32_t *pitch)
+{
+ int result;
+
+ result = compute_requirements(plane, num_bytes, alignment, pitch);
+
+ return result;
+}
+
+int
+tegra_2d_allocate_surface(struct tegra_2d_context *ctx,
+ struct tegra_2d_surface *surface)
+{
+ int result;
+ struct tegra_2d_ictx *ictx = (struct tegra_2d_ictx *) ctx;
+
+ if (ctx == NULL)
+ return TEGRA_2D_INVALID_PARAMETER;
+
+ ENTER();
+
+ result = allocate_surface(ictx, surface);
+
+ RETURN(result);
+}
+
+void
+tegra_2d_free_surface(struct tegra_2d_context *ctx,
+ struct tegra_2d_surface *surface)
+{
+ struct tegra_2d_ictx *ictx = (struct tegra_2d_ictx *) ctx;
+
+ if (ctx == NULL)
+ return;
+
+ ENTER();
+
+ free_surface(ictx, surface);
+
+ RETURN_VOID();
+}
+
+int
+tegra_2d_dump_surface(struct tegra_2d_context *ctx,
+ const struct tegra_2d_surface *surface,
+ const char *filename)
+{
+ int result;
+ struct tegra_2d_ictx *ictx = (struct tegra_2d_ictx *) ctx;
+
+ if (ctx == NULL)
+ return TEGRA_2D_INVALID_PARAMETER;
+
+ ENTER();
+
+ result = dump_surface(ictx, surface, filename);
+
+ RETURN(result);
+}
+
+void
+tegra_2d_color_convert(struct tegra_2d_surface_color *dst,
+ const struct tegra_2d_surface_color *src)
+{
+ color_convert(dst, src);
+}
+
+void
+tegra_2d_color_to_rgba(const struct tegra_2d_surface_color *src,
+ uint32_t *r,
+ uint32_t *g,
+ uint32_t *b,
+ uint32_t *a)
+{
+ color_to_rgba(src, r, g, b, a);
+}
+
+void
+tegra_2d_color_from_rgba(struct tegra_2d_surface_color *dst,
+ uint32_t r,
+ uint32_t g,
+ uint32_t b,
+ uint32_t a)
+{
+ color_from_rgba(dst, r, g, b, a);
+}
diff --git a/tegra/2d/tegra_2d_color.c b/tegra/2d/tegra_2d_color.c
new file mode 100644
index 0000000..089c5c2
--- /dev/null
+++ b/tegra/2d/tegra_2d_color.c
@@ -0,0 +1,412 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#include <stdlib.h>
+#include "tegra_2d.h"
+#include "tegra_2d_color.h"
+#include "tegra_2d_util.h"
+
+void
+color_convert(struct tegra_2d_surface_color *dst,
+ const struct tegra_2d_surface_color *src)
+{
+ int i;
+ uint32_t r, g, b, a;
+
+ ASSERT(dst);
+ ASSERT(src);
+
+ if (src->num_planes != dst->num_planes)
+ goto convert;
+
+ for (i=0; i<src->num_planes; ++i)
+ {
+ if (src->planes[i].format != dst->planes[i].format)
+ goto convert;
+
+ dst->planes[i].value = src->planes[i].value;
+ }
+
+ return;
+
+convert:
+ color_to_rgba(src, &r, &g, &b, &a);
+ color_from_rgba(dst, r, g, b, a);
+}
+
+static void
+rgb_to_yuv(uint32_t *y, uint32_t *u, uint32_t *v,
+ uint32_t r, uint32_t g, uint32_t b)
+{
+ int32_t yt, ut, vt;
+ yt = ((66 * r + 129 * g + 25 * b + 128) >> 8) + 16;
+ ut = ((-38 * (int32_t)r - 74 * (int32_t)g + 112 * (int32_t)b + 128) >> 8) + 128;
+ vt = ((112 * (int32_t)r - 94 * (int32_t)g - 18 * (int32_t)b + 128) >> 8) + 128;
+ *y = CLAMP(yt, 0, 255);
+ *u = CLAMP(ut, 0, 255);
+ *v = CLAMP(vt, 0, 255);
+}
+
+static void
+yuv_to_rgb(uint32_t *r, uint32_t *g, uint32_t *b,
+ uint32_t y, uint32_t u, uint32_t v)
+{
+ int32_t c = y - 16;
+ int32_t d = u - 128;
+ int32_t e = v - 128;
+ *r = CLAMP((298*c + 409*e + 128) >> 8, 0, 255);
+ *g = CLAMP(((298*c - 100*d - 208*e + 128) >> 8), 0, 255);
+ *b = CLAMP(((298*c + 516*d + 128) >> 8), 0, 255);
+}
+
+static void
+get_components(const struct tegra_2d_surface_color *src,
+ uint32_t *x,
+ uint32_t *y,
+ uint32_t *z,
+ uint32_t *w)
+{
+ int i;
+
+ for (i=0; i<src->num_planes; ++i)
+ {
+ uint32_t value = src->planes[i].value;
+
+ switch (src->planes[i].format)
+ {
+ case TEGRA_2D_FORMAT_A8R8G8B8:
+ *w = (value >> 24) & 0xff;
+ *x = (value >> 16) & 0xff;
+ *y = (value >> 8) & 0xff;
+ *z = (value >> 0) & 0xff;
+ break;
+
+ case TEGRA_2D_FORMAT_A8B8G8R8:
+ *w = (value >> 24) & 0xff;
+ *z = (value >> 16) & 0xff;
+ *y = (value >> 8) & 0xff;
+ *x = (value >> 0) & 0xff;
+ break;
+
+ case TEGRA_2D_FORMAT_R8G8B8A8:
+ *x = (value >> 24) & 0xff;
+ *y = (value >> 16) & 0xff;
+ *z = (value >> 8) & 0xff;
+ *w = (value >> 0) & 0xff;
+ break;
+
+ case TEGRA_2D_FORMAT_B8G8R8A8:
+ *z = (value >> 24) & 0xff;
+ *y = (value >> 16) & 0xff;
+ *x = (value >> 8) & 0xff;
+ *w = (value >> 0) & 0xff;
+ break;
+
+ case TEGRA_2D_FORMAT_A4R4G4B4:
+ *w = ((value >> 12) & 0x0f) << 4;
+ *x = ((value >> 8) & 0x0f) << 4;
+ *y = ((value >> 4) & 0x0f) << 4;
+ *z = ((value >> 0) & 0x0f) << 4;
+ break;
+
+ case TEGRA_2D_FORMAT_R4G4B4A4:
+ *x = ((value >> 12) & 0x0f) << 4;
+ *y = ((value >> 8) & 0x0f) << 4;
+ *z = ((value >> 4) & 0x0f) << 4;
+ *w = ((value >> 0) & 0x0f) << 4;
+ break;
+
+ case TEGRA_2D_FORMAT_R5G6B5:
+ *x = ((value >> 11) & 0x1f) << 3;
+ *y = ((value >> 5) & 0x3f) << 2;
+ *z = ((value >> 0) & 0x1f) << 3;
+ break;
+
+ case TEGRA_2D_FORMAT_A1R5G5B5:
+ *w = ((value >> 11) & 0x1f) << 3;
+ *x = ((value >> 6) & 0x1f) << 3;
+ *y = ((value >> 1) & 0x1f) << 3;
+ *z = ((value >> 0) & 0x01) << 7;
+ break;
+
+ case TEGRA_2D_FORMAT_Y8:
+ *x = value & 0xff;
+ break;
+
+ case TEGRA_2D_FORMAT_U8:
+ *y = value & 0xff;
+ break;
+
+ case TEGRA_2D_FORMAT_V8:
+ *z = value & 0xff;
+ break;
+
+ case TEGRA_2D_FORMAT_U8_V8:
+ *y = ((uint8_t *) &value)[0];
+ *z = ((uint8_t *) &value)[1];
+ break;
+
+ case TEGRA_2D_FORMAT_V8_U8:
+ *z = ((uint8_t *) &value)[0];
+ *y = ((uint8_t *) &value)[1];
+ break;
+
+ case TEGRA_2D_FORMAT_UYVY:
+ *y = ((uint8_t *) &value)[0];
+ *x = ((uint8_t *) &value)[1];
+ *z = ((uint8_t *) &value)[2];
+ break;
+
+ case TEGRA_2D_FORMAT_VYUY:
+ *z = ((uint8_t *) &value)[0];
+ *x = ((uint8_t *) &value)[1];
+ *y = ((uint8_t *) &value)[2];
+ break;
+
+ case TEGRA_2D_FORMAT_YUYV:
+ *x = ((uint8_t *) &value)[0];
+ *y = ((uint8_t *) &value)[1];
+ *z = ((uint8_t *) &value)[3];
+ break;
+
+ case TEGRA_2D_FORMAT_YVYU:
+ *x = ((uint8_t *) &value)[0];
+ *z = ((uint8_t *) &value)[1];
+ *y = ((uint8_t *) &value)[3];
+ break;
+
+ default:
+ ASSERT(0);
+ }
+ }
+}
+
+static void
+set_components(struct tegra_2d_surface_color *dst,
+ uint32_t x,
+ uint32_t y,
+ uint32_t z,
+ uint32_t w)
+{
+ int i;
+
+ for (i=0; i<dst->num_planes; ++i)
+ {
+ uint32_t value;
+
+ switch (dst->planes[i].format)
+ {
+ case TEGRA_2D_FORMAT_A8R8G8B8:
+ value = (w & 0xff) << 24;
+ value |= (x & 0xff) << 16;
+ value |= (y & 0xff) << 8;
+ value |= (z & 0xff) << 0;
+ break;
+
+ case TEGRA_2D_FORMAT_A8B8G8R8:
+ value = (w & 0xff) << 24;
+ value |= (z & 0xff) << 16;
+ value |= (y & 0xff) << 8;
+ value |= (x & 0xff) << 0;
+ break;
+
+ case TEGRA_2D_FORMAT_R8G8B8A8:
+ value = (x & 0xff) << 24;
+ value |= (y & 0xff) << 16;
+ value |= (z & 0xff) << 8;
+ value |= (w & 0xff) << 0;
+ break;
+
+ case TEGRA_2D_FORMAT_B8G8R8A8:
+ value = (z & 0xff) << 24;
+ value |= (y & 0xff) << 16;
+ value |= (x & 0xff) << 8;
+ value |= (w & 0xff) << 0;
+ break;
+
+ case TEGRA_2D_FORMAT_A4R4G4B4:
+ value = ((w >> 4) & 0x0f) << 12;
+ value |= ((x >> 4) & 0x0f) << 8;
+ value |= ((y >> 4) & 0x0f) << 4;
+ value |= ((z >> 4) & 0x0f) << 0;
+ break;
+
+ case TEGRA_2D_FORMAT_R4G4B4A4:
+ value = ((x >> 4) & 0x0f) << 12;
+ value |= ((y >> 4) & 0x0f) << 8;
+ value |= ((z >> 4) & 0x0f) << 4;
+ value |= ((w >> 4) & 0x0f) << 0;
+ break;
+
+ case TEGRA_2D_FORMAT_R5G6B5:
+ value = ((x >> 3) & 0x1f) << 11;
+ value |= ((y >> 2) & 0x3f) << 5;
+ value |= ((z >> 3) & 0x1f) << 0;
+ break;
+
+ case TEGRA_2D_FORMAT_A1R5G5B5:
+ value = ((w >> 3) & 0x1f) << 11;
+ value |= ((x >> 3) & 0x1f) << 6;
+ value |= ((y >> 3) & 0x1f) << 1;
+ value |= ((z >> 7) & 0x01) << 0;
+ break;
+
+ case TEGRA_2D_FORMAT_Y8:
+ value = x & 0xff;
+ break;
+
+ case TEGRA_2D_FORMAT_U8:
+ value = y & 0xff;
+ break;
+
+ case TEGRA_2D_FORMAT_V8:
+ value = z & 0xff;
+ break;
+
+ case TEGRA_2D_FORMAT_U8_V8:
+ ((uint8_t *) &value)[0] = y & 0xff;
+ ((uint8_t *) &value)[1] = z & 0xff;
+ break;
+
+ case TEGRA_2D_FORMAT_V8_U8:
+ ((uint8_t *) &value)[0] = z & 0xff;
+ ((uint8_t *) &value)[1] = y & 0xff;
+ break;
+
+ case TEGRA_2D_FORMAT_UYVY:
+ ((uint8_t *) &value)[0] = y & 0xff;
+ ((uint8_t *) &value)[1] = x & 0xff;
+ ((uint8_t *) &value)[2] = z & 0xff;
+ ((uint8_t *) &value)[3] = x & 0xff;
+ break;
+
+ case TEGRA_2D_FORMAT_VYUY:
+ ((uint8_t *) &value)[0] = z & 0xff;
+ ((uint8_t *) &value)[1] = x & 0xff;
+ ((uint8_t *) &value)[2] = y & 0xff;
+ ((uint8_t *) &value)[3] = x & 0xff;
+ break;
+
+ case TEGRA_2D_FORMAT_YUYV:
+ ((uint8_t *) &value)[0] = x & 0xff;
+ ((uint8_t *) &value)[1] = y & 0xff;
+ ((uint8_t *) &value)[2] = x & 0xff;
+ ((uint8_t *) &value)[3] = z & 0xff;
+ break;
+
+ case TEGRA_2D_FORMAT_YVYU:
+ ((uint8_t *) &value)[0] = x & 0xff;
+ ((uint8_t *) &value)[1] = z & 0xff;
+ ((uint8_t *) &value)[2] = x & 0xff;
+ ((uint8_t *) &value)[3] = y & 0xff;
+ break;
+
+ default:
+ ASSERT(0);
+ }
+
+ dst->planes[i].value = value;
+ }
+}
+
+void
+color_to_rgba(const struct tegra_2d_surface_color *src,
+ uint32_t *r,
+ uint32_t *g,
+ uint32_t *b,
+ uint32_t *a)
+{
+ ASSERT(src);
+ ASSERT(r && g && b && a);
+
+ if (TEGRA_2D_FORMAT_IS_YUV(src->planes[0].format))
+ {
+ uint32_t y, u, v;
+ y = 0;
+ u = 0;
+ v = 0;
+
+ get_components(src, &y, &u, &v, NULL);
+ yuv_to_rgb(r, g, b, y, u, v);
+ *a = 255;
+ }
+ else
+ {
+ get_components(src, r, g, b, a);
+ }
+}
+
+void
+color_from_rgba(struct tegra_2d_surface_color *dst,
+ uint32_t r,
+ uint32_t g,
+ uint32_t b,
+ uint32_t a)
+{
+ ASSERT(dst);
+
+ if (TEGRA_2D_FORMAT_IS_YUV(dst->planes[0].format))
+ {
+ uint32_t y, u, v;
+
+ rgb_to_yuv(&y, &u, &v, r, g, b);
+ set_components(dst, y, u, v, 255);
+ }
+ else
+ {
+ set_components(dst, r, g, b, a);
+ }
+}
+
+const char *
+format_to_str(enum tegra_2d_format format)
+{
+ switch (format)
+ {
+ #define CASE(f) case TEGRA_2D_FORMAT_##f: return #f
+ CASE(A8R8G8B8);
+ CASE(A8B8G8R8);
+ CASE(R8G8B8A8);
+ CASE(B8G8R8A8);
+ CASE(A4R4G4B4);
+ CASE(R4G4B4A4);
+ CASE(R5G6B5);
+ CASE(A1R5G5B5);
+ CASE(Y8);
+ CASE(U8);
+ CASE(V8);
+ CASE(U8_V8);
+ CASE(V8_U8);
+ CASE(UYVY);
+ CASE(VYUY);
+ CASE(YUYV);
+ CASE(YVYU);
+ #undef CASE
+
+ default:
+ return "unknown";
+ }
+}
diff --git a/tegra/2d/tegra_2d_color.h b/tegra/2d/tegra_2d_color.h
new file mode 100644
index 0000000..aceef6a
--- /dev/null
+++ b/tegra/2d/tegra_2d_color.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#ifndef TEGRA_2D_COLOR_H
+#define TEGRA_2D_COLOR_H
+
+void
+color_convert(struct tegra_2d_surface_color *dst,
+ const struct tegra_2d_surface_color *src);
+
+void
+color_to_rgba(const struct tegra_2d_surface_color *src,
+ uint32_t *r,
+ uint32_t *g,
+ uint32_t *b,
+ uint32_t *a);
+
+void
+color_from_rgba(struct tegra_2d_surface_color *dst,
+ uint32_t r,
+ uint32_t g,
+ uint32_t b,
+ uint32_t a);
+
+const char *
+format_to_str(enum tegra_2d_format format);
+
+#endif // TEGRA_2D_COLOR_H
diff --git a/tegra/2d/tegra_2d_context.c b/tegra/2d/tegra_2d_context.c
new file mode 100644
index 0000000..d03d7d5
--- /dev/null
+++ b/tegra/2d/tegra_2d_context.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#include <stdlib.h>
+#include "tegra_2d.h"
+#include "tegra_2d_context.h"
+#include "tegra_2d_util.h"
+
+struct tegra_2d_ictx *
+open2d(int fd)
+{
+ int i;
+ struct tegra_2d_ictx *ctx;
+
+ ctx = malloc(sizeof(struct tegra_2d_ictx));
+ if (ctx == NULL)
+ return NULL;
+
+ ctx->base.log_enable = 0;
+ ctx->base.dump_enable = 0;
+ ctx->base.dump_counter = 0;
+ ctx->base.dump_prefix[0] = 0;
+ ctx->device = NULL;
+ ctx->channel = NULL;
+ ctx->stream = NULL;
+ tegra_fence_clear(&ctx->pre_fence);
+ tegra_fence_clear(&ctx->post_fence);
+
+ ctx->device = tegra_device_create(fd);
+ if (ctx->device == NULL)
+ goto fail;
+
+ ctx->channel = tegra_channel_open(ctx->device, TEGRADRM_MODULEID_2D);
+ if (ctx->channel == NULL)
+ goto fail;
+
+ ctx->stream = tegra_stream_create(ctx->channel);
+ if (ctx->stream == NULL)
+ goto fail;
+
+ for (i=0; i<TEGRA_2D_MAX_PLANES; ++i)
+ {
+ g2fill_init(&ctx->g2fill[i]);
+ g2copy_init(&ctx->g2copy[i]);
+ frcopy_init(&ctx->frcopy[i]);
+ }
+
+ sbcopy_init(&ctx->sbcopy);
+
+ return ctx;
+
+fail:
+ close2d(ctx);
+ return NULL;
+}
+
+void
+close2d(struct tegra_2d_ictx *ctx)
+{
+ ASSERT(ctx);
+
+ tegra_stream_destroy(ctx->stream);
+ tegra_channel_close(ctx->channel);
+ tegra_device_destroy(ctx->device);
+
+ free(ctx);
+}
+
+int
+begin2d(struct tegra_2d_ictx *ctx,
+ const struct tegra_fence *fence)
+{
+ ASSERT(ctx);
+
+ if (fence != NULL)
+ tegra_fence_copy(&ctx->pre_fence, fence);
+ else
+ tegra_fence_clear(&ctx->pre_fence);
+
+ return TEGRA_2D_OK;
+}
+
+int
+flush2d(struct tegra_2d_ictx *ctx)
+{
+ int result;
+
+ ASSERT(ctx);
+
+ result = tegra_stream_flush(ctx->stream, &ctx->post_fence);
+
+ if (result != 0)
+ return TEGRA_2D_STREAM_FAILURE;
+
+ return TEGRA_2D_OK;
+}
+
+int
+end2d(struct tegra_2d_ictx *ctx,
+ struct tegra_fence *fence)
+{
+ int result;
+
+ ASSERT(ctx);
+
+ result = flush2d(ctx);
+
+ if (result != 0)
+ return result;
+
+ if (fence != NULL)
+ tegra_fence_copy(fence, &ctx->post_fence);
+ else
+ tegra_fence_wait(ctx->channel, &ctx->post_fence);
+
+ return TEGRA_2D_OK;
+}
diff --git a/tegra/2d/tegra_2d_context.h b/tegra/2d/tegra_2d_context.h
new file mode 100644
index 0000000..703f23b
--- /dev/null
+++ b/tegra/2d/tegra_2d_context.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#ifndef TEGRA_2D_CONTEXT_H
+#define TEGRA_2D_CONTEXT_H
+
+#include "tegra_drmif.h"
+#include "tegra_2d_g2fill.h"
+#include "tegra_2d_g2copy.h"
+#include "tegra_2d_frcopy.h"
+#include "tegra_2d_sbcopy.h"
+
+struct tegra_2d_ictx
+{
+ struct tegra_2d_context base;
+ struct tegra_device *device;
+ struct tegra_channel *channel;
+ struct tegra_stream *stream;
+ struct tegra_fence pre_fence;
+ struct tegra_fence post_fence;
+ struct tegra_2d_g2fill g2fill[TEGRA_2D_MAX_PLANES];
+ struct tegra_2d_g2copy g2copy[TEGRA_2D_MAX_PLANES];
+ struct tegra_2d_frcopy frcopy[TEGRA_2D_MAX_PLANES];
+ struct tegra_2d_sbcopy sbcopy;
+};
+
+struct tegra_2d_ictx *
+open2d(int fd);
+
+void
+close2d(struct tegra_2d_ictx *ctx);
+
+int
+begin2d(struct tegra_2d_ictx *ctx,
+ const struct tegra_fence *fence);
+
+int
+flush2d(struct tegra_2d_ictx *ctx);
+
+int
+end2d(struct tegra_2d_ictx *ctx,
+ struct tegra_fence *fence);
+
+#endif // TEGRA_2D_CONTEXT_H
diff --git a/tegra/2d/tegra_2d_copy.c b/tegra/2d/tegra_2d_copy.c
new file mode 100644
index 0000000..a659b5b
--- /dev/null
+++ b/tegra/2d/tegra_2d_copy.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#include <stdlib.h>
+#include "tegra_2d.h"
+#include "tegra_2d_context.h"
+#include "tegra_2d_copy.h"
+#include "tegra_2d_surface.h"
+#include "tegra_2d_util.h"
+#include "tegra_2d_g2copy.h"
+#include "tegra_2d_frcopy.h"
+#include "tegra_2d_sbcopy.h"
+
+static int
+copy_area(struct tegra_2d_ictx *ctx,
+ const struct tegra_2d_surface_area *dst_area,
+ const struct tegra_2d_surface_area *src_area,
+ enum tegra_2d_transform transform)
+{
+ int i;
+ int result = -1;
+ uint32_t num_words = 0;
+ uint32_t num_relocs = 0;
+
+ ASSERT(dst_area->surface->num_planes == src_area->surface->num_planes);
+
+ ctx->sbcopy.is_valid = 0;
+
+ for (i=0; i<dst_area->surface->num_planes; ++i)
+ {
+ result = frcopy_set(&ctx->frcopy[i],
+ &dst_area->planes[i],
+ &src_area->planes[i],
+ transform);
+ if (result == TEGRA_2D_OK)
+ {
+ num_words += frcopy_num_words(&ctx->frcopy[i]);
+ num_relocs += frcopy_num_relocs(&ctx->frcopy[i]);
+ continue;
+ }
+
+ result = g2copy_set(&ctx->g2copy[i],
+ &dst_area->planes[i],
+ &src_area->planes[i],
+ transform);
+ if (result == TEGRA_2D_OK)
+ {
+ num_words += g2copy_num_words(&ctx->g2copy[i]);
+ num_relocs += g2copy_num_relocs(&ctx->g2copy[i]);
+ continue;
+ }
+
+ break;
+ }
+
+ if (result != TEGRA_2D_OK)
+ {
+ result = sbcopy_set(&ctx->sbcopy,
+ dst_area,
+ src_area,
+ transform);
+ if (result != TEGRA_2D_OK)
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+
+ num_words = sbcopy_num_words(&ctx->sbcopy);
+ num_relocs = sbcopy_num_relocs(&ctx->sbcopy);
+ }
+
+ if (ctx->base.log_enable)
+ {
+ if (ctx->sbcopy.is_valid)
+ {
+ sbcopy_dump(&ctx->sbcopy);
+ }
+ else
+ {
+ for (i=0; i<dst_area->surface->num_planes; ++i)
+ {
+ if (ctx->frcopy[i].is_valid)
+ frcopy_dump(&ctx->frcopy[i]);
+ else
+ g2copy_dump(&ctx->g2copy[i]);
+ }
+ }
+ }
+
+ result = tegra_stream_begin(ctx->stream,
+ num_words,
+ &ctx->pre_fence,
+ tegra_fence_is_valid(&ctx->pre_fence) ?
+ 1 : 0,
+ 0,
+ num_relocs,
+ 0);
+ if (result != 0)
+ return TEGRA_2D_STREAM_FAILURE;
+
+ if (ctx->sbcopy.is_valid)
+ {
+ sbcopy_dispatch(&ctx->sbcopy, ctx->stream);
+ }
+ else
+ {
+ for (i=0; i<dst_area->surface->num_planes; ++i)
+ {
+ if (ctx->frcopy[i].is_valid)
+ frcopy_dispatch(&ctx->frcopy[i], ctx->stream);
+ else
+ g2copy_dispatch(&ctx->g2copy[i], ctx->stream);
+ }
+ }
+
+ tegra_stream_end(ctx->stream);
+
+ return TEGRA_2D_OK;
+}
+
+int
+copy2d(struct tegra_2d_ictx *ctx,
+ const struct tegra_2d_surface *dst,
+ const struct tegra_2d_surface *src,
+ const struct tegra_2d_rect *dst_rect,
+ const struct tegra_2d_rect *src_rect,
+ enum tegra_2d_transform transform)
+{
+ int result;
+ struct tegra_2d_rect vdst_rect;
+ struct tegra_2d_rect vsrc_rect;
+ struct tegra_2d_surface_area dst_area;
+ struct tegra_2d_surface_area src_area;
+
+ ASSERT(ctx);
+
+ if (dst == NULL)
+ return TEGRA_2D_INVALID_PARAMETER;
+
+ if (src == NULL)
+ return TEGRA_2D_INVALID_PARAMETER;
+
+ if (dst_rect == NULL)
+ {
+ vdst_rect.left = 0;
+ vdst_rect.top = 0;
+ vdst_rect.right = dst->planes[0].width;
+ vdst_rect.bottom = dst->planes[0].height;
+ }
+ else
+ {
+ result = validate_rect(dst, dst_rect);
+ if (result != TEGRA_2D_OK)
+ return result;
+
+ vdst_rect = *dst_rect;
+ }
+
+ if (src_rect == NULL)
+ {
+ vsrc_rect.left = 0;
+ vsrc_rect.top = 0;
+ vsrc_rect.right = src->planes[0].width;
+ vsrc_rect.bottom = src->planes[0].height;
+ }
+ else
+ {
+ result = validate_rect(src, src_rect);
+ if (result != TEGRA_2D_OK)
+ return result;
+
+ vsrc_rect = *src_rect;
+ }
+
+ compute_surface_area(&dst_area, dst, &vdst_rect);
+ compute_surface_area(&src_area, src, &vsrc_rect);
+
+ if (ctx->base.dump_enable)
+ dump_src(ctx, src);
+
+ result = copy_area(ctx, &dst_area, &src_area, transform);
+ if (result != TEGRA_2D_OK)
+ return result;
+
+ if (ctx->base.dump_enable)
+ dump_dst(ctx, dst);
+
+ return TEGRA_2D_OK;
+}
diff --git a/tegra/2d/tegra_2d_copy.h b/tegra/2d/tegra_2d_copy.h
new file mode 100644
index 0000000..b307245
--- /dev/null
+++ b/tegra/2d/tegra_2d_copy.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#ifndef TEGRA_2D_COPY_H
+#define TEGRA_2D_COPY_H
+
+int
+copy2d(struct tegra_2d_ictx *ctx,
+ const struct tegra_2d_surface *dst,
+ const struct tegra_2d_surface *src,
+ const struct tegra_2d_rect *dst_rect,
+ const struct tegra_2d_rect *src_rect,
+ enum tegra_2d_transform transform);
+
+#endif // TEGRA_2D_COPY_H
diff --git a/tegra/2d/tegra_2d_fill.c b/tegra/2d/tegra_2d_fill.c
new file mode 100644
index 0000000..8186b56
--- /dev/null
+++ b/tegra/2d/tegra_2d_fill.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#include <stdlib.h>
+#include "tegra_2d.h"
+#include "tegra_2d_context.h"
+#include "tegra_2d_fill.h"
+#include "tegra_2d_color.h"
+#include "tegra_2d_surface.h"
+#include "tegra_2d_util.h"
+
+static int
+fill_area(struct tegra_2d_ictx *ctx,
+ const struct tegra_2d_surface_area *dst_area,
+ const struct tegra_2d_surface_color *color)
+{
+ int i;
+ int result;
+ uint32_t num_words = 0;
+ uint32_t num_relocs = 0;
+
+ for (i=0; i<dst_area->surface->num_planes; ++i)
+ {
+ ASSERT(dst_area->planes[i].plane->format == color->planes[i].format);
+
+ result = g2fill_set(&ctx->g2fill[i],
+ &dst_area->planes[i],
+ &color->planes[i]);
+ if (result != TEGRA_2D_OK)
+ return result;
+
+ num_words += g2fill_num_words(&ctx->g2fill[i]);
+ num_relocs += g2fill_num_relocs(&ctx->g2fill[i]);
+ }
+
+ if (ctx->base.log_enable)
+ {
+ for (i=0; i<dst_area->surface->num_planes; ++i)
+ g2fill_dump(&ctx->g2fill[i]);
+ }
+
+ result = tegra_stream_begin(ctx->stream,
+ num_words,
+ &ctx->pre_fence,
+ tegra_fence_is_valid(&ctx->pre_fence) ?
+ 1 : 0,
+ 0,
+ num_relocs,
+ 0);
+ if (result != 0)
+ return TEGRA_2D_STREAM_FAILURE;
+
+ for (i=0; i<dst_area->surface->num_planes; ++i)
+ g2fill_dispatch(&ctx->g2fill[i], ctx->stream);
+
+ tegra_stream_end(ctx->stream);
+
+ return TEGRA_2D_OK;
+}
+
+int
+fill2d(struct tegra_2d_ictx *ctx,
+ const struct tegra_2d_surface *dst,
+ const struct tegra_2d_surface_color *color,
+ const struct tegra_2d_rect *dst_rect)
+{
+ int i;
+ int result;
+ struct tegra_2d_rect vdst_rect;
+ struct tegra_2d_surface_color vcolor;
+ struct tegra_2d_surface_area dst_area;
+
+ ASSERT(ctx);
+
+ if (dst == NULL)
+ return TEGRA_2D_INVALID_PARAMETER;
+
+ if (color == NULL)
+ return TEGRA_2D_INVALID_PARAMETER;
+
+ if (dst_rect == NULL)
+ {
+ vdst_rect.left = 0;
+ vdst_rect.top = 0;
+ vdst_rect.right = dst->planes[0].width;
+ vdst_rect.bottom = dst->planes[0].height;
+ }
+ else
+ {
+ result = validate_rect(dst, dst_rect);
+ if (result != TEGRA_2D_OK)
+ return result;
+
+ vdst_rect = *dst_rect;
+ }
+
+ vcolor.num_planes = dst->num_planes;
+ for (i=0; i<vcolor.num_planes; ++i)
+ vcolor.planes[i].format = dst->planes[i].format;
+
+ color_convert(&vcolor, color);
+
+ compute_surface_area(&dst_area, dst, &vdst_rect);
+
+ result = fill_area(ctx, &dst_area, &vcolor);
+ if (result != TEGRA_2D_OK)
+ return result;
+
+ if (ctx->base.dump_enable)
+ dump_dst(ctx, dst);
+
+ return TEGRA_2D_OK;
+}
diff --git a/tegra/2d/tegra_2d_fill.h b/tegra/2d/tegra_2d_fill.h
new file mode 100644
index 0000000..1d52baa
--- /dev/null
+++ b/tegra/2d/tegra_2d_fill.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#ifndef TEGRA_2D_FILL_H
+#define TEGRA_2D_FILL_H
+
+int
+fill2d(struct tegra_2d_ictx *ctx,
+ const struct tegra_2d_surface *dst,
+ const struct tegra_2d_surface_color *color,
+ const struct tegra_2d_rect *dst_rect);
+
+#endif // TEGRA_2D_FILL_H
diff --git a/tegra/2d/tegra_2d_frcopy.c b/tegra/2d/tegra_2d_frcopy.c
new file mode 100644
index 0000000..991d29d
--- /dev/null
+++ b/tegra/2d/tegra_2d_frcopy.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#include "tegra_drmif.h"
+#include "class_ids.h"
+#include "tegra_2d_frcopy.h"
+#include "tegra_2d_reg_g2sb.h"
+#include "tegra_2d_reg_host.h"
+
+uint32_t
+frcopy_num_words(const struct tegra_2d_frcopy *hw)
+{
+ return 1 + sizeof(hw->block) / sizeof(uint32_t);
+}
+
+uint32_t
+frcopy_num_relocs(const struct tegra_2d_frcopy *hw)
+{
+ return 2;
+}
+
+void
+frcopy_init(struct tegra_2d_frcopy *hw)
+{
+ ASSERT(hw);
+
+ hw->is_valid = 0;
+
+ GR2D_RESET(trigger);
+ GR2D_RESET(cmdsel);
+ GR2D_RESET(controlsecond);
+ GR2D_RESET(controlmain);
+ GR2D_RESET(tilemode);
+ GR2D_RESET(dstba);
+ GR2D_RESET(dstst);
+ GR2D_RESET(srcba);
+ GR2D_RESET(srcst);
+ GR2D_RESET(srcsize);
+
+ OPCODE_MASK2(op1,
+ trigger,
+ cmdsel);
+ OPCODE_MASK2(op2,
+ controlsecond,
+ controlmain);
+ OPCODE_NONINCR(op3, tilemode, 1);
+ OPCODE_MASK5(op4,
+ dstba,
+ dstst,
+ srcba,
+ srcst,
+ srcsize);
+
+ GR2D_VAL(trigger, trigger, gr2d_srcsize_r());
+ GR2D_DEF(cmdsel, sbor2d, g2);
+ GR2D_DEF(controlsecond, fr_mode, src_dst_copy);
+ GR2D_DEF(controlsecond, fr_readwait, enable);
+ GR2D_DEF(controlmain, cmdt, bitblt);
+}
+
+static uint32_t
+compute_offset(const struct tegra_2d_plane *plane,
+ uint32_t xpos,
+ uint32_t ypos)
+{
+ uint32_t offset;
+ uint32_t bytes_per_pixel = TEGRA_2D_FORMAT_BYTES(plane->format);
+ uint32_t pixels_per_line = plane->pitch / bytes_per_pixel;
+
+ if (plane->layout == TEGRA_2D_LAYOUT_LINEAR)
+ {
+ offset = ypos * plane->pitch;
+ offset += xpos * bytes_per_pixel;
+ }
+ else
+ {
+ uint32_t xb = xpos * bytes_per_pixel;
+ offset = 16 * pixels_per_line * (ypos / 16);
+ offset += 256 * (xb / 16);
+ offset += 16 * (ypos % 16);
+ offset += xb % 16;
+ }
+
+ return plane->mem_offset + offset;
+}
+
+int
+frcopy_set(struct tegra_2d_frcopy *hw,
+ const struct tegra_2d_plane_area *dst,
+ const struct tegra_2d_plane_area *src,
+ enum tegra_2d_transform transform)
+{
+ uint32_t block_size;
+ uint32_t align_mask;
+ uint32_t dst_xpos = dst->xpos;
+ uint32_t dst_ypos = dst->ypos;
+ uint32_t src_xpos = src->xpos;
+ uint32_t src_ypos = src->ypos;
+ uint32_t src_width = src->width;
+ uint32_t src_height = src->height;
+
+ ASSERT(hw);
+
+ hw->is_valid = 0;
+
+ if (dst->plane->mem_handle == NULL)
+ return TEGRA_2D_INVALID_BUFFER;
+
+ if (src->plane->mem_handle == NULL)
+ return TEGRA_2D_INVALID_BUFFER;
+
+ if (src_width > 4096 || src_height > 4096)
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+
+ if (src->plane->format != dst->plane->format)
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+
+ if (!equal_size_area(src, dst, transform))
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+
+ hw->dst_handle = dst->plane->mem_handle;
+ hw->dst_offset = compute_offset(dst->plane, dst_xpos, dst_ypos);
+ hw->src_handle = src->plane->mem_handle;
+ hw->src_offset = compute_offset(src->plane, src_xpos, src_ypos);
+
+ switch (transform)
+ {
+ #define CASE(transform, v) \
+ case TEGRA_2D_TRANSFORM_##transform: \
+ GR2D_DEF(controlsecond, fr_type, v); \
+ break
+ CASE(IDENTITY, identity);
+ CASE(ROT_90, rot_90);
+ CASE(ROT_180, rot_180);
+ CASE(ROT_270, rot_270);
+ CASE(FLIP_X, flip_x);
+ CASE(FLIP_Y, flip_y);
+ CASE(TRANSPOSE, trans_lr);
+ CASE(INV_TRANSPOSE, trans_rl);
+ #undef CASE
+ default:
+ ASSERT(0);
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+ }
+
+ switch (TEGRA_2D_FORMAT_BITS(dst->plane->format))
+ {
+ #define CASE(v) \
+ case v: \
+ GR2D_DEF(controlmain, dstcd, bpp##v); \
+ block_size = 128 / v; \
+ break
+ CASE(8);
+ CASE(16);
+ CASE(32);
+ #undef CASE
+ default:
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+ }
+
+ align_mask = block_size - 1;
+ #define CHECK_ALIGNMENT(v) ((((uint32_t) v) & align_mask) != 0)
+ if (CHECK_ALIGNMENT(src_width) ||
+ CHECK_ALIGNMENT(src_height) ||
+ CHECK_ALIGNMENT(src_xpos) ||
+ CHECK_ALIGNMENT(src_ypos) ||
+ CHECK_ALIGNMENT(dst_xpos) ||
+ CHECK_ALIGNMENT(dst_ypos))
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+ #undef CHECK_ALIGNMENT
+
+ GR2D_DEF(controlmain, srccd, same);
+
+ if (dst->plane->layout == TEGRA_2D_LAYOUT_TILED)
+ GR2D_DEF(tilemode, dst_wr_tile_mode, tiled);
+ else
+ GR2D_DEF(tilemode, dst_wr_tile_mode, linear);
+
+ if (src->plane->layout == TEGRA_2D_LAYOUT_TILED)
+ GR2D_DEF(tilemode, src_y_tile_mode, tiled);
+ else
+ GR2D_DEF(tilemode, src_y_tile_mode, linear);
+
+ GR2D_VAL(dstst, dsts, dst->plane->pitch);
+ GR2D_VAL(srcst, srcs, src->plane->pitch);
+ GR2D_VAL(srcsize, srcwidth, src_width - 1);
+ GR2D_VAL(srcsize, srcheight, src_height - 1);
+
+ hw->is_valid = 1;
+ return TEGRA_2D_OK;
+}
+
+void
+frcopy_dispatch(const struct tegra_2d_frcopy *hw,
+ struct tegra_stream *stream)
+{
+ ASSERT(hw);
+ ASSERT(hw->is_valid);
+ ASSERT(stream);
+
+ tegra_stream_push_setclass(stream, NV_GRAPHICS_2D_CLASS_ID);
+
+ tegra_stream_push_words(stream,
+ &hw->block,
+ sizeof(hw->block) / sizeof(uint32_t),
+ 2,
+ tegra_reloc(&hw->block.dstba,
+ hw->dst_handle,
+ hw->dst_offset),
+ tegra_reloc(&hw->block.srcba,
+ hw->src_handle,
+ hw->src_offset));
+}
+
+void
+frcopy_dump(const struct tegra_2d_frcopy *hw)
+{
+ char buffer[1024];
+ int offset = 0;
+ int space = ARRAY_SIZE(buffer);
+
+ ASSERT(hw);
+
+ offset = snprintf(buffer, space, "G2 Copy:\n");
+
+ #define PRINT(reg) \
+ offset += snprintf(buffer + offset, \
+ MAX(0, space - offset), \
+ "%18s: 0x%08x\n", \
+ #reg, \
+ hw->block.reg)
+
+ PRINT(op1);
+ PRINT(trigger);
+ PRINT(cmdsel);
+ PRINT(op2);
+ PRINT(controlsecond);
+ PRINT(controlmain);
+ PRINT(op3);
+ PRINT(tilemode);
+ PRINT(op4);
+ PRINT(dstba);
+ PRINT(dstst);
+ PRINT(srcba);
+ PRINT(srcst);
+ PRINT(srcsize);
+
+ #undef PRINT
+
+ LOG("%s", buffer);
+}
diff --git a/tegra/2d/tegra_2d_frcopy.h b/tegra/2d/tegra_2d_frcopy.h
new file mode 100644
index 0000000..f0ca115
--- /dev/null
+++ b/tegra/2d/tegra_2d_frcopy.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#ifndef TEGRA_2D_FRCOPY_H
+#define TEGRA_2D_FRCOPY_H
+
+#include <stdint.h>
+#include "tegra_2d.h"
+#include "tegra_2d_util.h"
+
+struct tegra_2d_frcopy
+{
+ struct tegra_2d_frcopy_block
+ {
+ uint32_t op1;
+ uint32_t trigger;
+ uint32_t cmdsel;
+
+ uint32_t op2;
+ uint32_t controlsecond;
+ uint32_t controlmain;
+
+ uint32_t op3;
+ uint32_t tilemode;
+
+ uint32_t op4;
+ uint32_t dstba;
+ uint32_t dstst;
+ uint32_t srcba;
+ uint32_t srcst;
+ uint32_t srcsize;
+ } block;
+ int is_valid;
+ struct tegra_bo *dst_handle;
+ struct tegra_bo *src_handle;
+ int dst_offset;
+ int src_offset;
+};
+
+uint32_t
+frcopy_num_words(const struct tegra_2d_frcopy *hw);
+
+uint32_t
+frcopy_num_relocs(const struct tegra_2d_frcopy *hw);
+
+void
+frcopy_init(struct tegra_2d_frcopy *hw);
+
+int
+frcopy_set(struct tegra_2d_frcopy *hw,
+ const struct tegra_2d_plane_area *dst,
+ const struct tegra_2d_plane_area *src,
+ enum tegra_2d_transform transform);
+
+void
+frcopy_dispatch(const struct tegra_2d_frcopy *hw,
+ struct tegra_stream *stream);
+
+void
+frcopy_dump(const struct tegra_2d_frcopy *hw);
+
+#endif // TEGRA_2D_FRCOPY_H
diff --git a/tegra/2d/tegra_2d_g2copy.c b/tegra/2d/tegra_2d_g2copy.c
new file mode 100644
index 0000000..9dccf25
--- /dev/null
+++ b/tegra/2d/tegra_2d_g2copy.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#include "tegra_drmif.h"
+#include "class_ids.h"
+#include "tegra_2d_g2copy.h"
+#include "tegra_2d_reg_g2sb.h"
+#include "tegra_2d_reg_host.h"
+
+uint32_t
+g2copy_num_words(const struct tegra_2d_g2copy *hw)
+{
+ return 1 + sizeof(hw->block) / sizeof(uint32_t);
+}
+
+uint32_t
+g2copy_num_relocs(const struct tegra_2d_g2copy *hw)
+{
+ return 2;
+}
+
+void
+g2copy_init(struct tegra_2d_g2copy *hw)
+{
+ ASSERT(hw);
+
+ hw->is_valid = 0;
+
+ GR2D_RESET(trigger);
+ GR2D_RESET(cmdsel);
+ GR2D_RESET(controlsecond);
+ GR2D_RESET(controlmain);
+ GR2D_RESET(ropfade);
+ GR2D_RESET(tilemode);
+ GR2D_RESET(dstba);
+ GR2D_RESET(dstst);
+ GR2D_RESET(srcba);
+ GR2D_RESET(srcst);
+ GR2D_RESET(dstsize);
+ GR2D_RESET(srcps);
+ GR2D_RESET(dstps);
+
+ OPCODE_MASK2(op1,
+ trigger,
+ cmdsel);
+ OPCODE_MASK3(op2,
+ controlsecond,
+ controlmain,
+ ropfade);
+ OPCODE_NONINCR(op3, tilemode, 1);
+ OPCODE_MASK7(op4,
+ dstba,
+ dstst,
+ srcba,
+ srcst,
+ dstsize,
+ srcps,
+ dstps);
+
+ GR2D_VAL(trigger, trigger, gr2d_dstps_r());
+ GR2D_DEF(cmdsel, sbor2d, g2);
+ GR2D_DEF(controlmain, cmdt, bitblt);
+ GR2D_VAL(ropfade, rop, 0xCC);
+}
+
+int
+g2copy_set(struct tegra_2d_g2copy *hw,
+ const struct tegra_2d_plane_area *dst,
+ const struct tegra_2d_plane_area *src,
+ enum tegra_2d_transform transform)
+{
+ int transpose;
+ int flip_x;
+ int flip_y;
+ uint32_t max_width;
+ uint32_t dst_xpos = dst->xpos;
+ uint32_t dst_ypos = dst->ypos;
+ uint32_t dst_width = dst->width;
+ uint32_t dst_height = dst->height;
+ uint32_t src_xpos = src->xpos;
+ uint32_t src_ypos = src->ypos;
+
+ ASSERT(hw);
+ ASSERT(dst);
+ ASSERT(src);
+
+ hw->is_valid = 0;
+
+ if (dst->plane->mem_handle == NULL)
+ return TEGRA_2D_INVALID_BUFFER;
+
+ if (src->plane->mem_handle == NULL)
+ return TEGRA_2D_INVALID_BUFFER;
+
+ if (src->plane->format != dst->plane->format)
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+
+ if (!equal_size_area(src, dst, transform))
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+
+ hw->dst_handle = dst->plane->mem_handle;
+ hw->dst_offset = dst->plane->mem_offset;
+ hw->src_handle = src->plane->mem_handle;
+ hw->src_offset = src->plane->mem_offset;
+
+ switch (transform)
+ {
+ #define CASE(transform, t, fx, fy) \
+ case TEGRA_2D_TRANSFORM_##transform: \
+ transpose = t; \
+ flip_x = fx; \
+ flip_y = fy; \
+ break
+ CASE(IDENTITY, 0, 0, 0);
+ CASE(ROT_90, 1, 0, 1);
+ CASE(ROT_180, 0, 1, 1);
+ CASE(ROT_270, 1, 1, 0);
+ CASE(FLIP_X, 0, 1, 0);
+ CASE(FLIP_Y, 0, 0, 1);
+ CASE(TRANSPOSE, 1, 0, 0);
+ CASE(INV_TRANSPOSE, 1, 1, 1);
+ #undef CASE
+ default:
+ ASSERT(0);
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+ }
+
+ if (flip_x)
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+
+ if (transpose)
+ GR2D_DEF(controlmain, xytdw, enable);
+ else
+ GR2D_DEF(controlmain, xytdw, disable);
+
+ switch (TEGRA_2D_FORMAT_BITS(dst->plane->format))
+ {
+ #define CASE(v, max) \
+ case v: \
+ GR2D_DEF(controlmain, dstcd, bpp##v); \
+ max_width = max; \
+ break
+ CASE(8, 32760);
+ CASE(16, 16384);
+ CASE(32, 8192);
+ #undef CASE
+ default:
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+ }
+
+ if (dst_width > max_width)
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+
+ GR2D_DEF(controlmain, srccd, same);
+
+ if (dst->plane->layout == TEGRA_2D_LAYOUT_TILED)
+ GR2D_DEF(tilemode, dst_wr_tile_mode, tiled);
+ else
+ GR2D_DEF(tilemode, dst_wr_tile_mode, linear);
+
+ if (src->plane->layout == TEGRA_2D_LAYOUT_TILED)
+ GR2D_DEF(tilemode, src_y_tile_mode, tiled);
+ else
+ GR2D_DEF(tilemode, src_y_tile_mode, linear);
+
+ GR2D_VAL(dstst, dsts, dst->plane->pitch);
+ GR2D_VAL(srcst, srcs, src->plane->pitch);
+ GR2D_VAL(dstsize, dstwidth, dst_width);
+ GR2D_VAL(dstsize, dstheight, dst_height);
+ GR2D_VAL(srcps, srcx, src_xpos);
+ GR2D_VAL(srcps, srcy, src_ypos);
+ GR2D_VAL(dstps, dstx, dst_xpos);
+ if (flip_y)
+ {
+ GR2D_DEF(controlmain, yflip, enable);
+ GR2D_VAL(dstps, dsty, dst_ypos + dst_height - 1);
+ }
+ else
+ {
+ GR2D_DEF(controlmain, yflip, disable);
+ GR2D_VAL(dstps, dsty, dst_ypos);
+ }
+
+ hw->is_valid = 1;
+ return TEGRA_2D_OK;
+}
+
+void
+g2copy_dispatch(const struct tegra_2d_g2copy *hw,
+ struct tegra_stream *stream)
+{
+ ASSERT(hw);
+ ASSERT(hw->is_valid);
+ ASSERT(stream);
+
+ tegra_stream_push_setclass(stream, NV_GRAPHICS_2D_CLASS_ID);
+
+ tegra_stream_push_words(stream,
+ &hw->block,
+ sizeof(hw->block) / sizeof(uint32_t),
+ 2,
+ tegra_reloc(&hw->block.dstba,
+ hw->dst_handle,
+ hw->dst_offset),
+ tegra_reloc(&hw->block.srcba,
+ hw->src_handle,
+ hw->src_offset));
+}
+
+void
+g2copy_dump(const struct tegra_2d_g2copy *hw)
+{
+ char buffer[1024];
+ int offset = 0;
+ int space = ARRAY_SIZE(buffer);
+
+ ASSERT(hw);
+
+ offset = snprintf(buffer, space, "G2 Copy:\n");
+
+ #define PRINT(reg) \
+ offset += snprintf(buffer + offset, \
+ MAX(0, space - offset), \
+ "%18s: 0x%08x\n", \
+ #reg, \
+ hw->block.reg)
+
+ PRINT(op1);
+ PRINT(trigger);
+ PRINT(cmdsel);
+ PRINT(op2);
+ PRINT(controlsecond);
+ PRINT(controlmain);
+ PRINT(ropfade);
+ PRINT(op3);
+ PRINT(tilemode);
+ PRINT(op4);
+ PRINT(dstba);
+ PRINT(dstst);
+ PRINT(srcba);
+ PRINT(srcst);
+ PRINT(dstsize);
+ PRINT(srcps);
+ PRINT(dstps);
+
+ #undef PRINT
+
+ LOG("%s", buffer);
+}
diff --git a/tegra/2d/tegra_2d_g2copy.h b/tegra/2d/tegra_2d_g2copy.h
new file mode 100644
index 0000000..22f79bc
--- /dev/null
+++ b/tegra/2d/tegra_2d_g2copy.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#ifndef TEGRA_2D_G2COPY_H
+#define TEGRA_2D_G2COPY_H
+
+#include <stdint.h>
+#include "tegra_2d.h"
+#include "tegra_2d_util.h"
+
+struct tegra_2d_g2copy
+{
+ struct tegra_2d_g2copy_block
+ {
+ uint32_t op1;
+ uint32_t trigger;
+ uint32_t cmdsel;
+
+ uint32_t op2;
+ uint32_t controlsecond;
+ uint32_t controlmain;
+ uint32_t ropfade;
+
+ uint32_t op3;
+ uint32_t tilemode;
+
+ uint32_t op4;
+ uint32_t dstba;
+ uint32_t dstst;
+ uint32_t srcba;
+ uint32_t srcst;
+ uint32_t dstsize;
+ uint32_t srcps;
+ uint32_t dstps;
+ } block;
+ int is_valid;
+ struct tegra_bo *dst_handle;
+ struct tegra_bo *src_handle;
+ int dst_offset;
+ int src_offset;
+};
+
+uint32_t
+g2copy_num_words(const struct tegra_2d_g2copy *hw);
+
+uint32_t
+g2copy_num_relocs(const struct tegra_2d_g2copy *hw);
+
+void
+g2copy_init(struct tegra_2d_g2copy *hw);
+
+int
+g2copy_set(struct tegra_2d_g2copy *hw,
+ const struct tegra_2d_plane_area *dst,
+ const struct tegra_2d_plane_area *src,
+ enum tegra_2d_transform transform);
+
+void
+g2copy_dispatch(const struct tegra_2d_g2copy *hw,
+ struct tegra_stream *stream);
+
+void
+g2copy_dump(const struct tegra_2d_g2copy *hw);
+
+#endif // TEGRA_2D_G2COPY_H
diff --git a/tegra/2d/tegra_2d_g2fill.c b/tegra/2d/tegra_2d_g2fill.c
new file mode 100644
index 0000000..91987c0
--- /dev/null
+++ b/tegra/2d/tegra_2d_g2fill.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#include "tegra_drmif.h"
+#include "class_ids.h"
+#include "tegra_2d_g2fill.h"
+#include "tegra_2d_reg_g2sb.h"
+#include "tegra_2d_reg_host.h"
+
+uint32_t
+g2fill_num_words(const struct tegra_2d_g2fill *hw)
+{
+ return 1 + (sizeof(hw->block) / sizeof(uint32_t));
+}
+
+uint32_t
+g2fill_num_relocs(const struct tegra_2d_g2fill *hw)
+{
+ return 1;
+}
+
+void
+g2fill_init(struct tegra_2d_g2fill *hw)
+{
+ ASSERT(hw);
+
+ hw->is_valid = 0;
+
+ GR2D_RESET(trigger);
+ GR2D_RESET(cmdsel);
+ GR2D_RESET(controlsecond);
+ GR2D_RESET(controlmain);
+ GR2D_RESET(ropfade);
+ GR2D_RESET(dstba);
+ GR2D_RESET(dstst);
+ GR2D_RESET(srcfgc);
+ GR2D_RESET(dstsize);
+ GR2D_RESET(dstps);
+
+ OPCODE_MASK2(op1,
+ trigger,
+ cmdsel);
+ OPCODE_MASK3(op2,
+ controlsecond,
+ controlmain,
+ ropfade);
+ OPCODE_MASK5(op3,
+ dstba,
+ dstst,
+ srcfgc,
+ dstsize,
+ dstps);
+
+ GR2D_VAL(trigger, trigger, gr2d_dstps_r());
+ GR2D_DEF(cmdsel, sbor2d, g2);
+ GR2D_DEF(controlmain, cmdt, bitblt);
+ GR2D_DEF(controlmain, turbofill, enable);
+ GR2D_DEF(controlmain, srcsld, enable);
+ GR2D_VAL(ropfade, rop, 0xCC);
+}
+
+int
+g2fill_set(struct tegra_2d_g2fill *hw,
+ const struct tegra_2d_plane_area *dst,
+ const struct tegra_2d_plane_color *color)
+{
+ int max_width;
+ uint32_t dst_xpos = dst->xpos;
+ uint32_t dst_ypos = dst->ypos;
+ uint32_t dst_width = dst->width;
+ uint32_t dst_height = dst->height;
+
+ ASSERT(hw);
+ ASSERT(dst);
+ ASSERT(color);
+
+ hw->is_valid = 0;
+
+ if (dst->plane->mem_handle == NULL)
+ return TEGRA_2D_INVALID_BUFFER;
+
+ hw->dst_handle = dst->plane->mem_handle;
+ hw->dst_offset = dst->plane->mem_offset;
+
+ switch (TEGRA_2D_FORMAT_BITS(dst->plane->format))
+ {
+ #define CASE(v, max) \
+ case v: \
+ GR2D_DEF(controlmain, dstcd, bpp##v); \
+ max_width = max; \
+ break
+ CASE(8, 32760);
+ CASE(16, 16384);
+ CASE(32, 8192);
+ #undef CASE
+ default:
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+ }
+
+ if (dst->width > max_width)
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+
+ GR2D_DEF(controlmain, srccd, same);
+ GR2D_VAL(dstst, dsts, dst->plane->pitch);
+ GR2D_VAL(srcfgc, srcfgc, color->value);
+ GR2D_VAL(dstsize, dstwidth, dst_width);
+ GR2D_VAL(dstsize, dstheight, dst_height);
+ GR2D_VAL(dstps, dstx, dst_xpos);
+ GR2D_VAL(dstps, dsty, dst_ypos);
+
+ hw->is_valid = 1;
+ return TEGRA_2D_OK;
+}
+
+void
+g2fill_dispatch(const struct tegra_2d_g2fill *hw,
+ struct tegra_stream *stream)
+{
+ ASSERT(hw);
+ ASSERT(hw->is_valid);
+ ASSERT(stream);
+
+ tegra_stream_push_setclass(stream, NV_GRAPHICS_2D_CLASS_ID);
+
+ tegra_stream_push_words(stream,
+ &hw->block,
+ sizeof(hw->block) / sizeof(uint32_t),
+ 1,
+ tegra_reloc(&hw->block.dstba,
+ hw->dst_handle,
+ hw->dst_offset));
+}
+
+void
+g2fill_dump(const struct tegra_2d_g2fill *hw)
+{
+ char buffer[1024];
+ int offset = 0;
+ int space = ARRAY_SIZE(buffer);
+
+ ASSERT(hw);
+
+ offset = snprintf(buffer, space, "G2 Fill:\n");
+
+ #define PRINT(reg) \
+ offset += snprintf(buffer + offset, \
+ MAX(0, space - offset), \
+ "%18s: 0x%08x\n", \
+ #reg, \
+ hw->block.reg)
+
+ PRINT(op1);
+ PRINT(trigger);
+ PRINT(cmdsel);
+ PRINT(op2);
+ PRINT(controlsecond);
+ PRINT(controlmain);
+ PRINT(ropfade);
+ PRINT(op3);
+ PRINT(dstba);
+ PRINT(dstst);
+ PRINT(srcfgc);
+ PRINT(dstsize);
+ PRINT(dstps);
+
+ #undef PRINT
+
+ LOG("%s", buffer);
+}
diff --git a/tegra/2d/tegra_2d_g2fill.h b/tegra/2d/tegra_2d_g2fill.h
new file mode 100644
index 0000000..e0715bd
--- /dev/null
+++ b/tegra/2d/tegra_2d_g2fill.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#ifndef TEGRA_2D_G2FILL_H
+#define TEGRA_2D_G2FILL_H
+
+#include <stdint.h>
+#include "tegra_2d.h"
+#include "tegra_2d_util.h"
+
+struct tegra_2d_g2fill
+{
+ struct tegra_2d_g2fill_block
+ {
+ uint32_t op1;
+ uint32_t trigger;
+ uint32_t cmdsel;
+
+ uint32_t op2;
+ uint32_t controlsecond;
+ uint32_t controlmain;
+ uint32_t ropfade;
+
+ uint32_t op3;
+ uint32_t dstba;
+ uint32_t dstst;
+ uint32_t srcfgc;
+ uint32_t dstsize;
+ uint32_t dstps;
+ } block;
+ int is_valid;
+ struct tegra_bo *dst_handle;
+ int dst_offset;
+};
+
+uint32_t
+g2fill_num_words(const struct tegra_2d_g2fill *hw);
+
+uint32_t
+g2fill_num_relocs(const struct tegra_2d_g2fill *hw);
+
+void
+g2fill_init(struct tegra_2d_g2fill *hw);
+
+int
+g2fill_set(struct tegra_2d_g2fill *hw,
+ const struct tegra_2d_plane_area *dst,
+ const struct tegra_2d_plane_color *color);
+
+void
+g2fill_dispatch(const struct tegra_2d_g2fill *hw,
+ struct tegra_stream *stream);
+
+void
+g2fill_dump(const struct tegra_2d_g2fill *hw);
+
+#endif // TEGRA_2D_G2FILL_H
diff --git a/tegra/2d/tegra_2d_reg_g2sb.h b/tegra/2d/tegra_2d_reg_g2sb.h
new file mode 100644
index 0000000..cbe09b0
--- /dev/null
+++ b/tegra/2d/tegra_2d_reg_g2sb.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#ifndef TEGRA_2D_REG_G2SB_H
+#define TEGRA_2D_REG_G2SB_H
+
+#include <stdint.h>
+#include "hw_gr2d.h"
+
+#define GR2D_RESET(reg) \
+ hw->block.reg = gr2d_##reg##_reset_val_v()
+
+#define GR2D_VAL(reg, field, value) \
+ hw->block.reg = (hw->block.reg & ~gr2d_##reg##_##field##_m()) \
+ | gr2d_##reg##_##field##_f((value))
+
+#define GR2D_DEF(reg, field, def) \
+ hw->block.reg = (hw->block.reg & ~gr2d_##reg##_##field##_m()) \
+ | gr2d_##reg##_##field##_f(gr2d_##reg##_##field##_##def##_v())
+
+static inline uint32_t gr2d_controlmain_yflip_disable_v(void)
+{
+ return gr2d_controlmain_yflip_dsiable_v();
+}
+static inline uint32_t gr2d_controlmain_turbofill_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlmain_turbofill_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_srccd_mono_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlmain_srccd_same_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_xytdw_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlmain_xytdw_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_srcdir_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlmain_srcdir_enable_v(void)
+{
+ return 1;
+}
+static inline uint32_t gr2d_controlmain_dstdir_disable_v(void)
+{
+ return 0;
+}
+static inline uint32_t gr2d_controlmain_dstdir_enable_v(void)
+{
+ return 1;
+}
+
+#endif // TEGRA_2D_REG_G2SB_H
diff --git a/tegra/2d/tegra_2d_reg_host.h b/tegra/2d/tegra_2d_reg_host.h
new file mode 100644
index 0000000..228d9bb
--- /dev/null
+++ b/tegra/2d/tegra_2d_reg_host.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#ifndef TEGRA_2D_REG_HOST_H
+#define TEGRA_2D_REG_HOST_H
+
+#include <stdint.h>
+#include "host1x01_hardware.h"
+#include "hw_gr2d.h"
+#include "tegra_2d_util.h"
+
+#define ADDR(reg) gr2d_##reg##_r()
+
+#define OPCODE_INCR(word, reg, count) \
+ hw->block.op = nvhost_opcode_nonincr(ADDR(reg), count)
+
+#define OPCODE_NONINCR(op, reg, count) \
+ hw->block.op = nvhost_opcode_nonincr(ADDR(reg), count)
+
+#define OPCODE_MASK(op, addr, mask) \
+ CT_ASSERT((mask) <= 0xffff); \
+ hw->block.op = nvhost_opcode_mask(addr, mask)
+
+#define OPCODE_MASK2(op, reg0, reg1) \
+ CT_ASSERT(ADDR(reg0) < ADDR(reg1)); \
+ CT_ASSERT(ADDR(reg1) - ADDR(reg0) < 16); \
+ OPCODE_MASK(op, ADDR(reg0), \
+ nvhost_mask2(ADDR(reg0), ADDR(reg0)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg1)))
+
+#define OPCODE_MASK3(op, reg0, reg1, reg2) \
+ CT_ASSERT(ADDR(reg0) < ADDR(reg1)); \
+ CT_ASSERT(ADDR(reg1) < ADDR(reg2)); \
+ CT_ASSERT(ADDR(reg2) - ADDR(reg0) < 16); \
+ OPCODE_MASK(op, ADDR(reg0), \
+ nvhost_mask2(ADDR(reg0), ADDR(reg0)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg1)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg2)))
+
+#define OPCODE_MASK4(op, reg0, reg1, reg2, reg3) \
+ CT_ASSERT(ADDR(reg0) < ADDR(reg1)); \
+ CT_ASSERT(ADDR(reg1) < ADDR(reg2)); \
+ CT_ASSERT(ADDR(reg2) < ADDR(reg3)); \
+ CT_ASSERT(ADDR(reg3) - ADDR(reg0) < 16); \
+ OPCODE_MASK(op, ADDR(reg0), \
+ nvhost_mask2(ADDR(reg0), ADDR(reg0)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg1)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg2)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg3)))
+
+#define OPCODE_MASK5(op, reg0, reg1, reg2, reg3, reg4) \
+ CT_ASSERT(ADDR(reg0) < ADDR(reg1)); \
+ CT_ASSERT(ADDR(reg1) < ADDR(reg2)); \
+ CT_ASSERT(ADDR(reg2) < ADDR(reg3)); \
+ CT_ASSERT(ADDR(reg3) < ADDR(reg4)); \
+ CT_ASSERT(ADDR(reg4) - ADDR(reg0) < 16); \
+ OPCODE_MASK(op, ADDR(reg0), \
+ nvhost_mask2(ADDR(reg0), ADDR(reg0)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg1)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg2)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg3)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg4)))
+
+#define OPCODE_MASK6(op, reg0, reg1, reg2, reg3, reg4, reg5) \
+ CT_ASSERT(ADDR(reg0) < ADDR(reg1)); \
+ CT_ASSERT(ADDR(reg1) < ADDR(reg2)); \
+ CT_ASSERT(ADDR(reg2) < ADDR(reg3)); \
+ CT_ASSERT(ADDR(reg3) < ADDR(reg4)); \
+ CT_ASSERT(ADDR(reg4) < ADDR(reg5)); \
+ CT_ASSERT(ADDR(reg5) - ADDR(reg0) < 16); \
+ OPCODE_MASK(op, ADDR(reg0), \
+ nvhost_mask2(ADDR(reg0), ADDR(reg0)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg1)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg2)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg3)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg4)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg5)))
+
+#define OPCODE_MASK7(op, reg0, reg1, reg2, reg3, reg4, reg5, reg6) \
+ CT_ASSERT(ADDR(reg0) < ADDR(reg1)); \
+ CT_ASSERT(ADDR(reg1) < ADDR(reg2)); \
+ CT_ASSERT(ADDR(reg2) < ADDR(reg3)); \
+ CT_ASSERT(ADDR(reg3) < ADDR(reg4)); \
+ CT_ASSERT(ADDR(reg4) < ADDR(reg5)); \
+ CT_ASSERT(ADDR(reg5) < ADDR(reg6)); \
+ CT_ASSERT(ADDR(reg6) - ADDR(reg0) < 16); \
+ OPCODE_MASK(op, ADDR(reg0), \
+ nvhost_mask2(ADDR(reg0), ADDR(reg0)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg1)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg2)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg3)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg4)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg5)) | \
+ nvhost_mask2(ADDR(reg0), ADDR(reg6)))
+
+#endif // TEGRA_2D_REG_HOST_H
diff --git a/tegra/2d/tegra_2d_sbcopy.c b/tegra/2d/tegra_2d_sbcopy.c
new file mode 100644
index 0000000..9b858ff
--- /dev/null
+++ b/tegra/2d/tegra_2d_sbcopy.c
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#include "tegra_drmif.h"
+#include "class_ids.h"
+#include "tegra_2d_sbcopy.h"
+#include "tegra_2d_reg_g2sb.h"
+#include "tegra_2d_reg_host.h"
+
+uint32_t
+sbcopy_num_words(const struct tegra_2d_sbcopy *hw)
+{
+ return 1 + sizeof(hw->block) / sizeof(uint32_t);
+}
+
+uint32_t
+sbcopy_num_relocs(const struct tegra_2d_sbcopy *hw)
+{
+ return 4;
+}
+
+void
+sbcopy_init(struct tegra_2d_sbcopy *hw)
+{
+ ASSERT(hw);
+
+ hw->is_valid = 0;
+
+ GR2D_RESET(trigger);
+ GR2D_RESET(cmdsel);
+ GR2D_RESET(vdda);
+ GR2D_RESET(vddaini);
+ GR2D_RESET(hdda);
+ GR2D_RESET(hddainils);
+ GR2D_RESET(sbformat);
+ GR2D_RESET(controlsb);
+ GR2D_RESET(controlsecond);
+ GR2D_RESET(controlmain);
+ GR2D_RESET(dstba);
+ GR2D_RESET(tilemode);
+ GR2D_RESET(srcba_sb_surfbase);
+ GR2D_RESET(dstba_sb_surfbase);
+ GR2D_RESET(dstst);
+ GR2D_RESET(srcba);
+ GR2D_RESET(srcst);
+ GR2D_RESET(srcsize);
+ GR2D_RESET(dstsize);
+
+ OPCODE_MASK6(op1,
+ trigger,
+ cmdsel,
+ vdda,
+ vddaini,
+ hdda,
+ hddainils);
+ OPCODE_MASK5(op2,
+ sbformat,
+ controlsb,
+ controlsecond,
+ controlmain,
+ dstba);
+ OPCODE_MASK3(op3,
+ tilemode,
+ srcba_sb_surfbase,
+ dstba_sb_surfbase);
+ OPCODE_MASK5(op4,
+ dstst,
+ srcba,
+ srcst,
+ srcsize,
+ dstsize);
+
+ GR2D_VAL(trigger, trigger, gr2d_dstsize_r());
+ GR2D_DEF(cmdsel, sbor2d, sb);
+ GR2D_DEF(controlmain, cmdt, bitblt);
+ GR2D_DEF(controlmain, srcdir, enable);
+ GR2D_DEF(controlmain, dstdir, enable);
+}
+
+int
+sbcopy_set(struct tegra_2d_sbcopy *hw,
+ const struct tegra_2d_surface_area *dst,
+ const struct tegra_2d_surface_area *src,
+ enum tegra_2d_transform transform)
+{
+ int transpose;
+ int flip_x;
+ int flip_y;
+ float inv_scale_x;
+ float inv_scale_y;
+ uint32_t dst_xpos = dst->planes[0].xpos;
+ uint32_t dst_ypos = dst->planes[0].ypos;
+ uint32_t dst_width = dst->planes[0].width;
+ uint32_t dst_height = dst->planes[0].height;
+ uint32_t src_xpos = src->planes[0].xpos;
+ uint32_t src_ypos = src->planes[0].ypos;
+ uint32_t src_width = src->planes[0].width;
+ uint32_t src_height = src->planes[0].height;
+
+ ASSERT(hw);
+ ASSERT(dst);
+ ASSERT(src);
+
+ hw->is_valid = 0;
+
+ if (dst->surface->num_planes > 1)
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+
+ if (src->surface->num_planes > 1)
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+
+ if (dst->planes[0].plane->mem_handle == NULL)
+ return TEGRA_2D_INVALID_BUFFER;
+
+ if (src->planes[0].plane->mem_handle == NULL)
+ return TEGRA_2D_INVALID_BUFFER;
+
+ hw->dst_handle = dst->planes[0].plane->mem_handle;
+ hw->dst_offset = dst->planes[0].plane->mem_offset +
+ (TEGRA_2D_FORMAT_BYTES(dst->planes[0].plane->format) *
+ dst_xpos) +
+ (dst->planes[0].plane->pitch * dst_ypos);
+ hw->src_handle = src->planes[0].plane->mem_handle;
+ hw->src_offset = src->planes[0].plane->mem_offset +
+ (TEGRA_2D_FORMAT_BYTES(src->planes[0].plane->format) *
+ src_xpos) +
+ (src->planes[0].plane->pitch * src_ypos);
+
+ switch (transform)
+ {
+ #define CASE(transform, t, fx, fy) \
+ case TEGRA_2D_TRANSFORM_##transform: \
+ transpose = t; \
+ flip_x = fx; \
+ flip_y = fy; \
+ break
+ CASE(IDENTITY, 0, 0, 0);
+ CASE(ROT_90, 1, 0, 1);
+ CASE(ROT_180, 0, 1, 1);
+ CASE(ROT_270, 1, 1, 0);
+ CASE(FLIP_X, 0, 1, 0);
+ CASE(FLIP_Y, 0, 0, 1);
+ CASE(TRANSPOSE, 1, 0, 0);
+ CASE(INV_TRANSPOSE, 1, 1, 1);
+ #undef CASE
+ default:
+ ASSERT(0);
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+ }
+
+ if (flip_x)
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+
+ #define FMT(sf, df) \
+ (TEGRA_2D_FORMAT_ID(sf) | (TEGRA_2D_FORMAT_ID(df) << 16))
+
+ switch (FMT(src->planes[0].plane->format, dst->planes[0].plane->format))
+ {
+ #define CASE(sf, df, sif, dif) \
+ case FMT(TEGRA_2D_FORMAT_##sf, TEGRA_2D_FORMAT_##df): \
+ GR2D_DEF(sbformat, sifmt, sif); \
+ GR2D_DEF(sbformat, difmt, dif); \
+ break
+ CASE(R5G6B5, R5G6B5, b5g6r5, b5g6r5);
+ CASE(R5G6B5, A1R5G5B5, b5g6r5, b5g6r5bs);
+ CASE(R5G6B5, A8B8G8R8, b5g6r5, r8g8b8a8);
+ CASE(R5G6B5, A8R8G8B8, b5g6r5, b8g8r8a8);
+ CASE(A1R5G5B5, R5G6B5, b5g6r5bs, b5g6r5);
+ CASE(A1R5G5B5, A1R5G5B5, b5g6r5bs, b5g6r5bs);
+ CASE(A1R5G5B5, A8B8G8R8, b5g6r5bs, r8g8b8a8);
+ CASE(A1R5G5B5, A8R8G8B8, b5g6r5bs, b8g8r8a8);
+ CASE(A8B8G8R8, R5G6B5, r8g8b8a8, b5g6r5);
+ CASE(A8B8G8R8, A1R5G5B5, r8g8b8a8, b5g6r5bs);
+ CASE(A8B8G8R8, A8B8G8R8, r8g8b8a8, r8g8b8a8);
+ CASE(A8B8G8R8, A8R8G8B8, r8g8b8a8, b8g8r8a8);
+ CASE(A8R8G8B8, R5G6B5, b8g8r8a8, b5g6r5);
+ CASE(A8R8G8B8, A1R5G5B5, b8g8r8a8, b5g6r5bs);
+ CASE(A8R8G8B8, A8B8G8R8, b8g8r8a8, r8g8b8a8);
+ CASE(A8R8G8B8, A8R8G8B8, b8g8r8a8, b8g8r8a8);
+ #undef CASE
+ default:
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+ }
+
+ if (transpose)
+ {
+ GR2D_DEF(controlmain, xytdw, enable);
+ inv_scale_x = ((float) src->planes[0].width - 1) /
+ (dst->planes[0].height - 1);
+ inv_scale_y = ((float) src->planes[0].height - 1) /
+ (dst->planes[0].width - 1);
+ }
+ else
+ {
+ GR2D_DEF(controlmain, xytdw, disable);
+ inv_scale_x = ((float) src->planes[0].width - 1) /
+ (dst->planes[0].width - 1);
+ inv_scale_y = ((float) src->planes[0].height - 1) /
+ (dst->planes[0].height - 1);
+ }
+
+ #define CHECK_SCALE(inv) \
+ if (inv > 64.0f || inv < 1.0f/4096.0f) \
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+ CHECK_SCALE(inv_scale_x);
+ CHECK_SCALE(inv_scale_y);
+ #undef CHECK_SCALE
+
+ GR2D_DEF(controlsb, discsc, disable);
+
+ if (inv_scale_x == 1.0f)
+ GR2D_DEF(controlsb, hftype, disable);
+ else if (inv_scale_x < 1.0f)
+ GR2D_DEF(controlsb, hftype, interp);
+ else if (inv_scale_x < 1.3f)
+ GR2D_DEF(controlsb, hftype, lpf1);
+ else if (inv_scale_x < 2.0f)
+ GR2D_DEF(controlsb, hftype, lpf3);
+ else
+ GR2D_DEF(controlsb, hftype, lpf6);
+
+ if (inv_scale_y == 1.0f)
+ {
+ GR2D_DEF(controlsb, vfen, disable);
+ }
+ else
+ {
+ GR2D_DEF(controlsb, vfen, enable);
+
+ if (inv_scale_y < 1.0f)
+ GR2D_DEF(controlsb, vftype, interp);
+ else if (inv_scale_y < 1.3f)
+ GR2D_DEF(controlsb, vftype, avg25_interp75);
+ else if (inv_scale_y < 2.0f)
+ GR2D_DEF(controlsb, vftype, avg50_interp50);
+ else
+ GR2D_DEF(controlsb, vftype, avg);
+ }
+
+ if (flip_y)
+ {
+ GR2D_DEF(controlmain, yflip, enable);
+ hw->dst_offset += dst->planes[0].plane->pitch *
+ (dst->planes[0].height - 1);
+ }
+ else
+ {
+ GR2D_DEF(controlmain, yflip, disable);
+ }
+
+ switch (TEGRA_2D_FORMAT_BITS(dst->planes[0].plane->format))
+ {
+ #define CASE(v) \
+ case v: \
+ GR2D_DEF(controlmain, dstcd, bpp##v); \
+ break
+ CASE(8);
+ CASE(16);
+ CASE(32);
+ #undef CASE
+ default:
+ return TEGRA_2D_UNSUPPORTED_BLIT;
+ }
+
+ GR2D_VAL(vdda, vdstep, FLOAT_TO_FIXED_6_12(inv_scale_y));
+ GR2D_VAL(vddaini, vdtini, FLOAT_TO_FIXED_0_8(src->planes[0].ypos));
+ GR2D_VAL(hdda, hdstep, FLOAT_TO_FIXED_6_12(inv_scale_x));
+ GR2D_VAL(hddainils, hdini, FLOAT_TO_FIXED_0_8(src->planes[0].xpos));
+
+
+ if (dst->planes[0].plane->layout == TEGRA_2D_LAYOUT_TILED)
+ GR2D_DEF(tilemode, dst_wr_tile_mode, tiled);
+ else
+ GR2D_DEF(tilemode, dst_wr_tile_mode, linear);
+
+ if (src->planes[0].plane->layout == TEGRA_2D_LAYOUT_TILED)
+ GR2D_DEF(tilemode, src_y_tile_mode, tiled);
+ else
+ GR2D_DEF(tilemode, src_y_tile_mode, linear);
+
+ GR2D_VAL(dstst, dsts, dst->planes[0].plane->pitch);
+ GR2D_VAL(srcst, srcs, src->planes[0].plane->pitch);
+ GR2D_VAL(srcsize, srcwidth, src_width);
+ GR2D_VAL(srcsize, srcheight, src_height - 1);
+ GR2D_VAL(dstsize, dstwidth, dst_width);
+ GR2D_VAL(dstsize, dstheight, dst_height - 1);
+
+ hw->is_valid = 1;
+ return TEGRA_2D_OK;
+}
+
+void
+sbcopy_dispatch(const struct tegra_2d_sbcopy *hw,
+ struct tegra_stream *stream)
+{
+ ASSERT(hw);
+ ASSERT(hw->is_valid);
+ ASSERT(stream);
+
+ tegra_stream_push_setclass(stream, NV_GRAPHICS_2D_SB_CLASS_ID);
+
+ tegra_stream_push_words(stream,
+ &hw->block,
+ sizeof(hw->block) / sizeof(uint32_t),
+ 4,
+ tegra_reloc(&hw->block.dstba,
+ hw->dst_handle,
+ hw->dst_offset),
+ tegra_reloc(&hw->block.srcba_sb_surfbase,
+ hw->src_handle,
+ hw->src_offset),
+ tegra_reloc(&hw->block.dstba_sb_surfbase,
+ hw->dst_handle,
+ hw->dst_offset),
+ tegra_reloc(&hw->block.srcba,
+ hw->src_handle,
+ hw->src_offset));
+}
+
+void
+sbcopy_dump(const struct tegra_2d_sbcopy *hw)
+{
+ char buffer[1024];
+ int offset = 0;
+ int space = ARRAY_SIZE(buffer);
+
+ ASSERT(hw);
+
+ offset = snprintf(buffer, space, "G2 Copy:\n");
+
+ #define PRINT(reg) \
+ offset += snprintf(buffer + offset, \
+ MAX(0, space - offset), \
+ "%18s: 0x%08x\n", \
+ #reg, \
+ hw->block.reg)
+
+ PRINT(op1);
+ PRINT(trigger);
+ PRINT(cmdsel);
+ PRINT(vdda);
+ PRINT(vddaini);
+ PRINT(hdda);
+ PRINT(hddainils);
+ PRINT(op2);
+ PRINT(sbformat);
+ PRINT(controlsb);
+ PRINT(controlsecond);
+ PRINT(controlmain);
+ PRINT(dstba);
+ PRINT(op3);
+ PRINT(tilemode);
+ PRINT(srcba_sb_surfbase);
+ PRINT(dstba_sb_surfbase);
+ PRINT(op4);
+ PRINT(dstst);
+ PRINT(srcba);
+ PRINT(srcst);
+ PRINT(srcsize);
+ PRINT(dstsize);
+
+ #undef PRINT
+
+ LOG("%s", buffer);
+}
diff --git a/tegra/2d/tegra_2d_sbcopy.h b/tegra/2d/tegra_2d_sbcopy.h
new file mode 100644
index 0000000..38abad2
--- /dev/null
+++ b/tegra/2d/tegra_2d_sbcopy.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#ifndef TEGRA_2D_SBCOPY_H
+#define TEGRA_2D_SBCOPY_H
+
+#include <stdint.h>
+#include "tegra_2d.h"
+#include "tegra_2d_util.h"
+
+struct tegra_2d_sbcopy
+{
+ struct tegra_2d_sbcopy_block
+ {
+ uint32_t op1;
+ uint32_t trigger;
+ uint32_t cmdsel;
+ uint32_t vdda;
+ uint32_t vddaini;
+ uint32_t hdda;
+ uint32_t hddainils;
+
+ uint32_t op2;
+ uint32_t sbformat;
+ uint32_t controlsb;
+ uint32_t controlsecond;
+ uint32_t controlmain;
+ uint32_t dstba;
+
+ uint32_t op3;
+ uint32_t tilemode;
+ uint32_t srcba_sb_surfbase;
+ uint32_t dstba_sb_surfbase;
+
+ uint32_t op4;
+ uint32_t dstst;
+ uint32_t srcba;
+ uint32_t srcst;
+ uint32_t srcsize;
+ uint32_t dstsize;
+ } block;
+ int is_valid;
+ struct tegra_bo *dst_handle;
+ struct tegra_bo *src_handle;
+ int dst_offset;
+ int src_offset;
+};
+
+uint32_t
+sbcopy_num_words(const struct tegra_2d_sbcopy *hw);
+
+uint32_t
+sbcopy_num_relocs(const struct tegra_2d_sbcopy *hw);
+
+void
+sbcopy_init(struct tegra_2d_sbcopy *hw);
+
+int
+sbcopy_set(struct tegra_2d_sbcopy *hw,
+ const struct tegra_2d_surface_area *dst,
+ const struct tegra_2d_surface_area *src,
+ enum tegra_2d_transform transform);
+
+void
+sbcopy_dispatch(const struct tegra_2d_sbcopy *hw,
+ struct tegra_stream *stream);
+
+void
+sbcopy_dump(const struct tegra_2d_sbcopy *hw);
+
+#endif // TEGRA_2D_SBCOPY_H
diff --git a/tegra/2d/tegra_2d_surface.c b/tegra/2d/tegra_2d_surface.c
new file mode 100644
index 0000000..5d64adc
--- /dev/null
+++ b/tegra/2d/tegra_2d_surface.c
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "tegra_2d.h"
+#include "tegra_2d_context.h"
+#include "tegra_2d_surface.h"
+#include "tegra_2d_color.h"
+#include "tegra_2d_util.h"
+
+int
+compute_requirements(const struct tegra_2d_plane *plane,
+ uint32_t *num_bytes,
+ uint32_t *alignment,
+ uint32_t *pitch)
+{
+ uint32_t num_lines;
+ uint32_t bytes_per_line;
+ uint32_t bytes_per_pixel;
+
+ if (plane == NULL ||
+ num_bytes == NULL ||
+ alignment == NULL ||
+ pitch == NULL)
+ return TEGRA_2D_INVALID_PARAMETER;
+
+ num_lines = plane->height + 1;
+ bytes_per_pixel = TEGRA_2D_FORMAT_BYTES(plane->format);
+
+ if (plane->layout == TEGRA_2D_LAYOUT_LINEAR)
+ {
+ *alignment = 16;
+ bytes_per_line = ROUND_UP(plane->width * bytes_per_pixel, 32);
+ }
+ else
+ {
+ *alignment = 256;
+ bytes_per_line = ROUND_UP(plane->width * bytes_per_pixel, 64);
+ }
+
+ *pitch = bytes_per_line;
+ *num_bytes = (num_lines * bytes_per_line) + bytes_per_pixel;
+
+ return TEGRA_2D_OK;
+}
+
+int
+allocate_surface(struct tegra_2d_ictx *ctx,
+ struct tegra_2d_surface *surface)
+{
+ int i;
+ int result;
+ uint32_t num_bytes = 0;
+ uint32_t alignment = 1;
+ struct tegra_bo *mem_handle;
+
+ ASSERT(ctx);
+
+ if (surface == NULL)
+ return TEGRA_2D_INVALID_PARAMETER;
+
+ for (i=0; i<surface->num_planes; ++i)
+ {
+ uint32_t nb, a, p;
+ struct tegra_2d_plane *plane = &surface->planes[i];
+
+ result = compute_requirements(plane, &nb, &a, &p);
+ if (result != TEGRA_2D_OK)
+ return result;
+
+ num_bytes = ROUND_UP(num_bytes, a);
+
+ plane->pitch = p;
+ plane->mem_handle = NULL;
+ plane->mem_offset = num_bytes;
+
+ num_bytes += nb;
+ alignment = MAX(alignment, a);
+ }
+
+ mem_handle = tegra_bo_allocate(ctx->device,
+ num_bytes,
+ alignment);
+ if (mem_handle == NULL)
+ return TEGRA_2D_MEMORY_FAILURE;
+
+ for (i=0; i<surface->num_planes; ++i)
+ surface->planes[i].mem_handle = mem_handle;
+
+ return TEGRA_2D_OK;
+}
+
+void
+free_surface(struct tegra_2d_ictx *ctx,
+ struct tegra_2d_surface *surface)
+{
+ int i;
+
+ ASSERT(ctx);
+
+ if (surface == NULL)
+ return;
+
+ tegra_bo_free(surface->planes[0].mem_handle);
+
+ for (i=0; i<surface->num_planes; ++i)
+ surface->planes[i].mem_handle = NULL;
+}
+
+int
+dump_surface(struct tegra_2d_ictx *ctx,
+ const struct tegra_2d_surface *surface,
+ const char *filename)
+{
+ int i;
+ int result;
+ FILE *fp;
+
+ ASSERT(ctx);
+
+ if (surface == NULL)
+ return TEGRA_2D_INVALID_PARAMETER;
+
+ if (filename == NULL)
+ return TEGRA_2D_INVALID_PARAMETER;
+
+ LOG("Dumping: %s\n", filename);
+
+ fp = fopen(filename, "wb");
+ if (fp == NULL)
+ return TEGRA_2D_FILE_FAILURE;
+
+ result = TEGRA_2D_OK;
+
+ for (i=0; i<surface->num_planes; ++i)
+ {
+ void *ptr;
+ uint8_t *src;
+ uint32_t bytes_per_pixel;
+ uint32_t bytes_per_line;
+ uint32_t num_lines;
+ const struct tegra_2d_plane *plane = &surface->planes[i];
+
+ if (plane->mem_handle == NULL)
+ {
+ result = TEGRA_2D_INVALID_BUFFER;
+ goto exit;
+ }
+
+ bytes_per_pixel = TEGRA_2D_FORMAT_BYTES(plane->format);
+ bytes_per_line = plane->width * bytes_per_pixel;
+ num_lines = plane->height;
+
+ ptr = tegra_bo_map(plane->mem_handle);
+ if (ptr == NULL)
+ {
+ result = TEGRA_2D_MEMORY_FAILURE;
+ goto exit;
+ }
+
+ src = ((uint8_t *) ptr) + plane->mem_offset;
+
+ while (num_lines > 0)
+ {
+ fwrite(src, 1, bytes_per_line, fp);
+ src += plane->pitch;
+ --num_lines;
+ }
+
+ tegra_bo_unmap(plane->mem_handle);
+ }
+
+exit:
+ fclose(fp);
+ return result;
+}
+
+static void
+compute_dump_name(char *buffer,
+ size_t buffer_size,
+ const struct tegra_2d_surface *surface,
+ const char *label,
+ const char *prefix,
+ int counter)
+{
+ int i;
+ int offset = 0;
+ int space = buffer_size;
+
+ offset += snprintf(buffer + offset,
+ MAX(0, space - offset),
+ "%stegra_2d_%d_%s_",
+ prefix,
+ counter,
+ label);
+
+ for (i=0; i<surface->num_planes; ++i)
+ {
+ offset += snprintf(buffer + offset,
+ MAX(0, space - offset),
+ "%s%dx%dx%s",
+ i == 0 ? "" : "-",
+ surface->planes[i].width,
+ surface->planes[i].height,
+ format_to_str(surface->planes[i].format));
+ }
+
+ offset += snprintf(buffer + offset,
+ MAX(0, space - offset),
+ ".raw");
+}
+
+void
+dump_src(struct tegra_2d_ictx *ctx,
+ const struct tegra_2d_surface *src)
+{
+ char filename[FILENAME_MAX];
+
+ ASSERT(ctx);
+ ASSERT(src);
+
+ compute_dump_name(filename,
+ ARRAY_SIZE(filename),
+ src,
+ "src",
+ ctx->base.dump_prefix,
+ ctx->base.dump_counter);
+
+ tegra_fence_wait(ctx->channel, &ctx->pre_fence);
+
+ dump_surface(ctx, src, filename);
+}
+
+void
+dump_dst(struct tegra_2d_ictx *ctx,
+ const struct tegra_2d_surface *dst)
+{
+ char filename[FILENAME_MAX];
+
+ ASSERT(ctx);
+ ASSERT(dst);
+
+ compute_dump_name(filename,
+ ARRAY_SIZE(filename),
+ dst,
+ "dst",
+ ctx->base.dump_prefix,
+ ctx->base.dump_counter);
+
+ flush2d(ctx);
+ tegra_fence_wait(ctx->channel, &ctx->post_fence);
+
+ dump_surface(ctx, dst, filename);
+
+ ++ctx->base.dump_counter;
+}
diff --git a/tegra/2d/tegra_2d_surface.h b/tegra/2d/tegra_2d_surface.h
new file mode 100644
index 0000000..8e3dc1e
--- /dev/null
+++ b/tegra/2d/tegra_2d_surface.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#ifndef TEGRA_2D_SURFACE_H
+#define TEGRA_2D_SURFACE_H
+
+int
+compute_requirements(const struct tegra_2d_plane *plane,
+ uint32_t *num_bytes,
+ uint32_t *alignment,
+ uint32_t *pitch);
+
+int
+allocate_surface(struct tegra_2d_ictx *ctx,
+ struct tegra_2d_surface *surface);
+
+void
+free_surface(struct tegra_2d_ictx *ctx,
+ struct tegra_2d_surface *surface);
+
+int
+dump_surface(struct tegra_2d_ictx *ctx,
+ const struct tegra_2d_surface *surface,
+ const char *filename);
+
+void
+dump_src(struct tegra_2d_ictx *ctx,
+ const struct tegra_2d_surface *src);
+
+void
+dump_dst(struct tegra_2d_ictx *ctx,
+ const struct tegra_2d_surface *dst);
+
+#endif // TEGRA_2D_SURFACE_H
diff --git a/tegra/2d/tegra_2d_util.c b/tegra/2d/tegra_2d_util.c
new file mode 100644
index 0000000..ea2e407
--- /dev/null
+++ b/tegra/2d/tegra_2d_util.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#include "tegra_2d.h"
+#include "tegra_2d_util.h"
+
+void
+compute_surface_area(struct tegra_2d_surface_area *area,
+ const struct tegra_2d_surface *surface,
+ const struct tegra_2d_rect *rect)
+{
+ int i;
+ float xpos;
+ float ypos;
+ float width;
+ float height;
+
+ ASSERT(area);
+ ASSERT(surface);
+ ASSERT(rect);
+
+ area->surface = surface;
+
+ xpos = rect->left;
+ ypos = rect->top;
+ width = RECT_WIDTH(*rect);
+ height = RECT_HEIGHT(*rect);
+
+ for (i=0; i<surface->num_planes; ++i)
+ {
+ const struct tegra_2d_plane *p = &surface->planes[i];
+ struct tegra_2d_plane_area *pa = &area->planes[i];
+
+ pa->plane = p;
+ pa->xpos = (xpos * p->width) / surface->planes[0].width;
+ pa->ypos = (ypos * p->height) / surface->planes[0].height;
+ pa->width = (width * p->width) / surface->planes[0].width;
+ pa->height = (height * p->height) / surface->planes[0].height;
+ }
+}
+
+int
+validate_rect(const struct tegra_2d_surface *surface,
+ const struct tegra_2d_rect *rect)
+{
+ if (rect->left < 0 ||
+ rect->left >= rect->right ||
+ rect->top < 0 ||
+ rect->top >= rect->bottom ||
+ rect->right > surface->planes[0].width ||
+ rect->bottom > surface->planes[0].height)
+ return TEGRA_2D_INVALID_RECT;
+
+ return TEGRA_2D_OK;
+}
+
+int
+transform_swaps_xy(enum tegra_2d_transform transform)
+{
+ switch (transform)
+ {
+ case TEGRA_2D_TRANSFORM_ROT_90:
+ case TEGRA_2D_TRANSFORM_ROT_270:
+ case TEGRA_2D_TRANSFORM_TRANSPOSE:
+ case TEGRA_2D_TRANSFORM_INV_TRANSPOSE:
+ return 1;
+ default:
+ case TEGRA_2D_TRANSFORM_IDENTITY:
+ case TEGRA_2D_TRANSFORM_ROT_180:
+ case TEGRA_2D_TRANSFORM_FLIP_X:
+ case TEGRA_2D_TRANSFORM_FLIP_Y:
+ return 0;
+ }
+}
+
+int
+equal_size_area(const struct tegra_2d_plane_area *a,
+ const struct tegra_2d_plane_area *b,
+ enum tegra_2d_transform transform)
+{
+ #define CHECK(fa, fb) \
+ if (fabs(fa - fb) >= 0.001f) \
+ return 0
+
+ if (transform_swaps_xy(transform))
+ {
+ CHECK(a->width, b->height);
+ CHECK(a->height, b->width);
+ }
+ else
+ {
+ CHECK(a->width, b->width);
+ CHECK(b->height, b->height);
+ }
+
+ #undef CHECK
+
+ return 1;
+}
+
+const char *
+result_to_str(enum tegra_2d_result result)
+{
+ switch (result)
+ {
+ #define CASE(r) case TEGRA_2D_##r: return #r
+ CASE(OK);
+ CASE(INVALID_PARAMETER);
+ CASE(INVALID_RECT);
+ CASE(INVALID_BUFFER);
+ CASE(UNSUPPORTED_BLIT);
+ CASE(MEMORY_FAILURE);
+ CASE(STREAM_FAILURE);
+ CASE(CHANNEL_FAILURE);
+ CASE(DEVICE_FAILURE);
+ CASE(FILE_FAILURE);
+ #undef CASE
+
+ default:
+ return "unknown result";
+ }
+}
diff --git a/tegra/2d/tegra_2d_util.h b/tegra/2d/tegra_2d_util.h
new file mode 100644
index 0000000..70bd25a
--- /dev/null
+++ b/tegra/2d/tegra_2d_util.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#ifndef TEGRA_2D_UTIL_H
+#define TEGRA_2D_UTIL_H
+
+#include <assert.h>
+#include <stdio.h>
+#include <math.h>
+
+#define ASSERT assert
+#define CT_ASSERT(x) ((void) sizeof(char[1 - 2*!(x)]))
+
+#define MIN(a, b) (a < b ? a : b)
+#define MAX(a, b) (a > b ? a : b)
+
+#define CLAMP(x, l, h) (((x) < (l)) ? (l) : ((x) > (h) ? (h) : (x)))
+
+#define ROUND_UP(v, a) (v + (a - 1)) & ~(a - 1)
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+#define RECT_WIDTH(r) ((r).right - (r).left)
+#define RECT_HEIGHT(r) ((r).bottom - (r).top)
+
+#define FLOAT_TO_FIXED_6_12(fp) (((int32_t) (fp * 4096.0f + 0.5f)) & ((1<<18)-1))
+#define FLOAT_TO_FIXED_0_8(fp) (((int32_t) (fp * 256.0f + 0.5f)) & ((1<<8)-1))
+
+#define LOG(...) printf("[TEGRA_2D] " __VA_ARGS__)
+
+struct tegra_2d_plane_area
+{
+ const struct tegra_2d_plane *plane;
+ float xpos;
+ float ypos;
+ float width;
+ float height;
+};
+
+struct tegra_2d_surface_area
+{
+ const struct tegra_2d_surface *surface;
+ struct tegra_2d_plane_area planes[TEGRA_2D_MAX_PLANES];
+};
+
+void
+compute_surface_area(struct tegra_2d_surface_area *area,
+ const struct tegra_2d_surface *surface,
+ const struct tegra_2d_rect *rect);
+
+int
+validate_rect(const struct tegra_2d_surface *surface,
+ const struct tegra_2d_rect *rect);
+
+int
+equal_size_area(const struct tegra_2d_plane_area *a,
+ const struct tegra_2d_plane_area *b,
+ enum tegra_2d_transform transform);
+
+int
+transform_swaps_xy(enum tegra_2d_transform transform);
+
+const char *
+result_to_str(enum tegra_2d_result result);
+
+#endif // TEGRA_2D_UTIL_H
diff --git a/tegra/Makefile.am b/tegra/Makefile.am
index 72675e5..34a49d5 100644
--- a/tegra/Makefile.am
+++ b/tegra/Makefile.am
@@ -11,7 +11,18 @@ libdrm_tegra_la_LDFLAGS = -version-number 1:0:0 -no-undefined
libdrm_tegra_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
libdrm_tegra_la_SOURCES = \
- tegra_drm.c
+ tegra_drm.c \
+ 2d/tegra_2d_api.c \
+ 2d/tegra_2d_color.c \
+ 2d/tegra_2d_context.c \
+ 2d/tegra_2d_copy.c \
+ 2d/tegra_2d_fill.c \
+ 2d/tegra_2d_frcopy.c \
+ 2d/tegra_2d_g2copy.c \
+ 2d/tegra_2d_g2fill.c \
+ 2d/tegra_2d_sbcopy.c \
+ 2d/tegra_2d_surface.c \
+ 2d/tegra_2d_util.c
libdrm_tegracommonincludedir = ${includedir}/tegra
libdrm_tegracommoninclude_HEADERS = \
diff --git a/tegra/tegra_2d.h b/tegra/tegra_2d.h
new file mode 100644
index 0000000..a6d2f2f
--- /dev/null
+++ b/tegra/tegra_2d.h
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Francis Hart <fhart@nvidia.com>
+ */
+
+#ifndef TEGRA_2D_H
+#define TEGRA_2D_H
+
+#include <stdint.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct tegra_fence;
+
+struct tegra_2d_context
+{
+ int log_enable;
+ int dump_enable;
+ int dump_counter;
+ char dump_prefix[FILENAME_MAX];
+};
+
+struct tegra_2d_rect
+{
+ float left;
+ float top;
+ float right;
+ float bottom;
+};
+
+enum tegra_2d_layout
+{
+ TEGRA_2D_LAYOUT_LINEAR,
+ TEGRA_2D_LAYOUT_TILED,
+};
+
+#define TEGRA_2D_FORMAT(id, yuv, bpp) \
+ ((id << 16) | (yuv << 8) | (bpp))
+
+#define TEGRA_2D_FORMAT_BITS(f) \
+ ((f) & 0xff)
+
+#define TEGRA_2D_FORMAT_BYTES(f) \
+ (TEGRA_2D_FORMAT_BITS(f) >> 3)
+
+#define TEGRA_2D_FORMAT_IS_YUV(f) \
+ (((f) >> 8) & 0xff)
+
+#define TEGRA_2D_FORMAT_ID(f) \
+ (((f) >> 16) & 0xff)
+
+enum tegra_2d_format
+{
+ TEGRA_2D_FORMAT_A8R8G8B8 = TEGRA_2D_FORMAT( 1, 0, 32),
+ TEGRA_2D_FORMAT_A8B8G8R8 = TEGRA_2D_FORMAT( 2, 0, 32),
+ TEGRA_2D_FORMAT_R8G8B8A8 = TEGRA_2D_FORMAT( 3, 0, 32),
+ TEGRA_2D_FORMAT_B8G8R8A8 = TEGRA_2D_FORMAT( 4, 0, 32),
+ TEGRA_2D_FORMAT_A4R4G4B4 = TEGRA_2D_FORMAT( 5, 0, 16),
+ TEGRA_2D_FORMAT_R4G4B4A4 = TEGRA_2D_FORMAT( 6, 0, 16),
+ TEGRA_2D_FORMAT_R5G6B5 = TEGRA_2D_FORMAT( 7, 0, 16),
+ TEGRA_2D_FORMAT_A1R5G5B5 = TEGRA_2D_FORMAT( 8, 0, 16),
+ TEGRA_2D_FORMAT_Y8 = TEGRA_2D_FORMAT( 9, 1, 8),
+ TEGRA_2D_FORMAT_U8 = TEGRA_2D_FORMAT(10, 1, 8),
+ TEGRA_2D_FORMAT_V8 = TEGRA_2D_FORMAT(11, 1, 8),
+ TEGRA_2D_FORMAT_U8_V8 = TEGRA_2D_FORMAT(12, 1, 16),
+ TEGRA_2D_FORMAT_V8_U8 = TEGRA_2D_FORMAT(13, 1, 16),
+ TEGRA_2D_FORMAT_UYVY = TEGRA_2D_FORMAT(14, 1, 32),
+ TEGRA_2D_FORMAT_VYUY = TEGRA_2D_FORMAT(15, 1, 32),
+ TEGRA_2D_FORMAT_YUYV = TEGRA_2D_FORMAT(16, 1, 32),
+ TEGRA_2D_FORMAT_YVYU = TEGRA_2D_FORMAT(17, 1, 32),
+};
+
+enum tegra_2d_transform
+{
+ TEGRA_2D_TRANSFORM_IDENTITY,
+ TEGRA_2D_TRANSFORM_ROT_90,
+ TEGRA_2D_TRANSFORM_ROT_180,
+ TEGRA_2D_TRANSFORM_ROT_270,
+ TEGRA_2D_TRANSFORM_FLIP_X,
+ TEGRA_2D_TRANSFORM_FLIP_Y,
+ TEGRA_2D_TRANSFORM_TRANSPOSE,
+ TEGRA_2D_TRANSFORM_INV_TRANSPOSE
+};
+
+enum tegra_2d_result
+{
+ TEGRA_2D_OK,
+ TEGRA_2D_INVALID_PARAMETER,
+ TEGRA_2D_INVALID_RECT,
+ TEGRA_2D_INVALID_BUFFER,
+ TEGRA_2D_UNSUPPORTED_BLIT,
+ TEGRA_2D_MEMORY_FAILURE,
+ TEGRA_2D_STREAM_FAILURE,
+ TEGRA_2D_CHANNEL_FAILURE,
+ TEGRA_2D_DEVICE_FAILURE,
+ TEGRA_2D_FILE_FAILURE
+};
+
+struct tegra_2d_plane
+{
+ int width;
+ int height;
+ int pitch;
+ enum tegra_2d_format format;
+ enum tegra_2d_layout layout;
+ struct tegra_bo *mem_handle;
+ uint32_t mem_offset;
+};
+
+struct tegra_2d_plane_color
+{
+ uint32_t value;
+ enum tegra_2d_format format;
+};
+
+#define TEGRA_2D_MAX_PLANES 3
+
+struct tegra_2d_surface
+{
+ int num_planes;
+ struct tegra_2d_plane planes[TEGRA_2D_MAX_PLANES];
+};
+
+struct tegra_2d_surface_color
+{
+ int num_planes;
+ struct tegra_2d_plane_color planes[TEGRA_2D_MAX_PLANES];
+};
+
+struct tegra_2d_context *
+tegra_2d_open(int fd);
+
+void
+tegra_2d_close(struct tegra_2d_context *ctx);
+
+int
+tegra_2d_begin(struct tegra_2d_context *ctx,
+ const struct tegra_fence *fence);
+
+int
+tegra_2d_end(struct tegra_2d_context *ctx,
+ struct tegra_fence *fence);
+
+int
+tegra_2d_fill(struct tegra_2d_context *ctx,
+ const struct tegra_2d_surface *dst,
+ const struct tegra_2d_surface_color *color,
+ const struct tegra_2d_rect *dst_rect);
+
+int
+tegra_2d_copy(struct tegra_2d_context *ctx,
+ const struct tegra_2d_surface *dst,
+ const struct tegra_2d_surface *src,
+ const struct tegra_2d_rect *dst_rect,
+ const struct tegra_2d_rect *src_rect,
+ enum tegra_2d_transform transform);
+
+int
+tegra_2d_compute_requirements(const struct tegra_2d_plane *plane,
+ uint32_t *num_bytes,
+ uint32_t *alignment,
+ uint32_t *pitch);
+
+int
+tegra_2d_allocate_surface(struct tegra_2d_context *ctx,
+ struct tegra_2d_surface *surface);
+
+void
+tegra_2d_free_surface(struct tegra_2d_context *ctx,
+ struct tegra_2d_surface *surface);
+
+int
+tegra_2d_dump_surface(struct tegra_2d_context *ctx,
+ const struct tegra_2d_surface *surface,
+ const char *filename);
+
+void
+tegra_2d_color_convert(struct tegra_2d_surface_color *dst,
+ const struct tegra_2d_surface_color *src);
+
+void
+tegra_2d_color_to_rgba(const struct tegra_2d_surface_color *src,
+ uint32_t *r,
+ uint32_t *g,
+ uint32_t *b,
+ uint32_t *a);
+
+void
+tegra_2d_color_from_rgba(struct tegra_2d_surface_color *dst,
+ uint32_t r,
+ uint32_t g,
+ uint32_t b,
+ uint32_t a);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // TEGRA_2D_H
--
1.7.9.5
^ permalink raw reply related [flat|nested] 16+ messages in thread