summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary King <gking@nvidia.com>2010-02-05 17:40:32 -0800
committerGerrit Code Review <fermi-cygwin@git-master-01.nvidia.com>2010-02-05 17:40:33 -0800
commit17d14e6752a0eb7c53e8fa35f53af0cc338a0f92 (patch)
treed783fe5425857e3139c5a026b89f2ec6f5d7b535
parent445c49e7b4946dda7745e3a149c6ef4e4ff830b1 (diff)
parent56e5188ccbd8ddc5645c5cf188d3307b9e995dcb (diff)
Merge "tegra: integrate AVP transport RM service to kernel" into android-tegra-2.6.29
-rw-r--r--arch/arm/mach-tegra/include/ap15/ararb_sema.h177
-rw-r--r--arch/arm/mach-tegra/include/ap15/arictlr_arbgnt.h183
-rw-r--r--arch/arm/mach-tegra/include/ap15/arres_sema.h325
-rw-r--r--arch/arm/mach-tegra/include/avp.h144
-rw-r--r--arch/arm/mach-tegra/include/nvrm_avp_shrd_interrupt.h117
-rw-r--r--arch/arm/mach-tegra/include/nvrm_transport.h361
-rw-r--r--arch/arm/mach-tegra/include/nvrm_xpc.h157
-rw-r--r--arch/arm/mach-tegra/nvrm/core/ap15/Makefile2
-rw-r--r--arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_init.c7
-rw-r--r--arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_xpc.c432
-rw-r--r--arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_xpc_hw_private.c165
-rw-r--r--arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_xpc_hw_private.h92
-rw-r--r--arch/arm/mach-tegra/nvrm/core/common/Makefile1
-rw-r--r--arch/arm/mach-tegra/nvrm/core/common/nvrm_message.h270
-rw-r--r--arch/arm/mach-tegra/nvrm/core/common/nvrm_rpc.h208
-rw-r--r--arch/arm/mach-tegra/nvrm/core/common/nvrm_transport.c1655
-rw-r--r--arch/arm/mach-tegra/nvrm/dispatch/Makefile2
-rw-r--r--arch/arm/mach-tegra/nvrm/dispatch/NvRm_Dispatch.c11
-rw-r--r--arch/arm/mach-tegra/nvrm/dispatch/nvrm_transport_dispatch.c657
-rw-r--r--arch/arm/mach-tegra/nvrm/dispatch/nvrm_xpc_dispatch.c348
20 files changed, 5313 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/include/ap15/ararb_sema.h b/arch/arm/mach-tegra/include/ap15/ararb_sema.h
new file mode 100644
index 000000000000..adc9b4af14b0
--- /dev/null
+++ b/arch/arm/mach-tegra/include/ap15/ararb_sema.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+//
+// DO NOT EDIT - generated by simspec!
+//
+
+#ifndef ___ARARB_SEMA_H_INC_
+#define ___ARARB_SEMA_H_INC_
+// Arbitration semaphores provide a mechanism by which the two processors can arbitrate
+// for the use of various resources. These semaphores provide a hardware locking mechanism,
+// so that when a processor is already using a resource, the second processor is not
+// granted that resource. There are 32 bits of Arbitration semaphores provided in the system.
+// The hardware does not enforce any resource association to these bits. It is left to the
+// firmware to assign and use these bits.
+// Any processor that needs to access a particular resource will request for the
+// corresponding bit in the Arbitration semaphores by writing a one to that bit in the
+// Arbitration Semaphore Request register (SMP_GET register). Firmware will then
+// check the corresponding bit in the Semaphore Granted Status register (SMP_GNT_ST register)
+// If the requesting processor has been granted the resource, then the status returned will
+// be a one.
+// Alternately, the processor can configure the interrupt controller to generate an
+// interrupt when the resource becomes available. Refer to the arictlr_arbgnt specfile for details.
+// When the processor has finished using the resource, it releases the resource by writing a one
+// to the corresponding bit in the Arbitration Semaphore Put Request register
+// (SMP_PUT register). Additionally, pending request status is provided through the
+// Arbitration Request Pending Status register (SMP_REQ_ST register).
+// Semaphore Granted Status Register
+
+// Register ARB_SEMA_SMP_GNT_ST_0
+#define ARB_SEMA_SMP_GNT_ST_0 _MK_ADDR_CONST(0x0)
+#define ARB_SEMA_SMP_GNT_ST_0_WORD_COUNT 0x1
+#define ARB_SEMA_SMP_GNT_ST_0_RESET_VAL _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_GNT_ST_0_RESET_MASK _MK_MASK_CONST(0xffffffff)
+#define ARB_SEMA_SMP_GNT_ST_0_SW_DEFAULT_VAL _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_GNT_ST_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_GNT_ST_0_READ_MASK _MK_MASK_CONST(0xffffffff)
+#define ARB_SEMA_SMP_GNT_ST_0_WRITE_MASK _MK_MASK_CONST(0x0)
+// A one in any bit indicates that the processor reading this register as granted status for that bit. A zero indicates semaphore not granted.
+#define ARB_SEMA_SMP_GNT_ST_0_ARB_31_ARB_0_SHIFT _MK_SHIFT_CONST(0)
+#define ARB_SEMA_SMP_GNT_ST_0_ARB_31_ARB_0_FIELD (_MK_MASK_CONST(0xffffffff) << ARB_SEMA_SMP_GNT_ST_0_ARB_31_ARB_0_SHIFT)
+#define ARB_SEMA_SMP_GNT_ST_0_ARB_31_ARB_0_RANGE 31:0
+#define ARB_SEMA_SMP_GNT_ST_0_ARB_31_ARB_0_WOFFSET 0x0
+#define ARB_SEMA_SMP_GNT_ST_0_ARB_31_ARB_0_DEFAULT _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_GNT_ST_0_ARB_31_ARB_0_DEFAULT_MASK _MK_MASK_CONST(0xffffffff)
+#define ARB_SEMA_SMP_GNT_ST_0_ARB_31_ARB_0_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_GNT_ST_0_ARB_31_ARB_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+
+// Request Arbitration Semaphore Register
+
+// Register ARB_SEMA_SMP_GET_0
+#define ARB_SEMA_SMP_GET_0 _MK_ADDR_CONST(0x4)
+#define ARB_SEMA_SMP_GET_0_WORD_COUNT 0x1
+#define ARB_SEMA_SMP_GET_0_RESET_VAL _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_GET_0_RESET_MASK _MK_MASK_CONST(0xffffffff)
+#define ARB_SEMA_SMP_GET_0_SW_DEFAULT_VAL _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_GET_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_GET_0_READ_MASK _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_GET_0_WRITE_MASK _MK_MASK_CONST(0xffffffff)
+// Writing a one in any bit is a request for that semaphore bit by the processor performing the register write.
+#define ARB_SEMA_SMP_GET_0_GET_31_GET_0_SHIFT _MK_SHIFT_CONST(0)
+#define ARB_SEMA_SMP_GET_0_GET_31_GET_0_FIELD (_MK_MASK_CONST(0xffffffff) << ARB_SEMA_SMP_GET_0_GET_31_GET_0_SHIFT)
+#define ARB_SEMA_SMP_GET_0_GET_31_GET_0_RANGE 31:0
+#define ARB_SEMA_SMP_GET_0_GET_31_GET_0_WOFFSET 0x0
+#define ARB_SEMA_SMP_GET_0_GET_31_GET_0_DEFAULT _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_GET_0_GET_31_GET_0_DEFAULT_MASK _MK_MASK_CONST(0xffffffff)
+#define ARB_SEMA_SMP_GET_0_GET_31_GET_0_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_GET_0_GET_31_GET_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+
+// Arbitration Semaphore Put Request Register
+
+// Register ARB_SEMA_SMP_PUT_0
+#define ARB_SEMA_SMP_PUT_0 _MK_ADDR_CONST(0x8)
+#define ARB_SEMA_SMP_PUT_0_WORD_COUNT 0x1
+#define ARB_SEMA_SMP_PUT_0_RESET_VAL _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_PUT_0_RESET_MASK _MK_MASK_CONST(0xffffffff)
+#define ARB_SEMA_SMP_PUT_0_SW_DEFAULT_VAL _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_PUT_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_PUT_0_READ_MASK _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_PUT_0_WRITE_MASK _MK_MASK_CONST(0x0)
+// Writing a one in any bit will clear the corresponding semaphore bit by the processor performing the register write.
+#define ARB_SEMA_SMP_PUT_0_PUT_31_PUT_0_SHIFT _MK_SHIFT_CONST(0)
+#define ARB_SEMA_SMP_PUT_0_PUT_31_PUT_0_FIELD (_MK_MASK_CONST(0xffffffff) << ARB_SEMA_SMP_PUT_0_PUT_31_PUT_0_SHIFT)
+#define ARB_SEMA_SMP_PUT_0_PUT_31_PUT_0_RANGE 31:0
+#define ARB_SEMA_SMP_PUT_0_PUT_31_PUT_0_WOFFSET 0x0
+#define ARB_SEMA_SMP_PUT_0_PUT_31_PUT_0_DEFAULT _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_PUT_0_PUT_31_PUT_0_DEFAULT_MASK _MK_MASK_CONST(0xffffffff)
+#define ARB_SEMA_SMP_PUT_0_PUT_31_PUT_0_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_PUT_0_PUT_31_PUT_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+
+// Arbitration Request Pending Status (1=PENDING) Register
+
+// Register ARB_SEMA_SMP_REQ_ST_0
+#define ARB_SEMA_SMP_REQ_ST_0 _MK_ADDR_CONST(0xc)
+#define ARB_SEMA_SMP_REQ_ST_0_WORD_COUNT 0x1
+#define ARB_SEMA_SMP_REQ_ST_0_RESET_VAL _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_REQ_ST_0_RESET_MASK _MK_MASK_CONST(0xffffffff)
+#define ARB_SEMA_SMP_REQ_ST_0_SW_DEFAULT_VAL _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_REQ_ST_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_REQ_ST_0_READ_MASK _MK_MASK_CONST(0xffffffff)
+#define ARB_SEMA_SMP_REQ_ST_0_WRITE_MASK _MK_MASK_CONST(0x0)
+// A one in any bit indicates a request pending status. The corresponding bits are set when the request for the individual resource is pending. The read by CPU of this register shows the pending status for CPU and a read of this register by AVP (COP) shows the pending status for AVP.
+#define ARB_SEMA_SMP_REQ_ST_0_REQ_31_REQ_0_SHIFT _MK_SHIFT_CONST(0)
+#define ARB_SEMA_SMP_REQ_ST_0_REQ_31_REQ_0_FIELD (_MK_MASK_CONST(0xffffffff) << ARB_SEMA_SMP_REQ_ST_0_REQ_31_REQ_0_SHIFT)
+#define ARB_SEMA_SMP_REQ_ST_0_REQ_31_REQ_0_RANGE 31:0
+#define ARB_SEMA_SMP_REQ_ST_0_REQ_31_REQ_0_WOFFSET 0x0
+#define ARB_SEMA_SMP_REQ_ST_0_REQ_31_REQ_0_DEFAULT _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_REQ_ST_0_REQ_31_REQ_0_DEFAULT_MASK _MK_MASK_CONST(0xffffffff)
+#define ARB_SEMA_SMP_REQ_ST_0_REQ_31_REQ_0_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define ARB_SEMA_SMP_REQ_ST_0_REQ_31_REQ_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+
+
+//
+// REGISTER LIST
+//
+#define LIST_ARARB_SEMA_REGS(_op_) \
+_op_(ARB_SEMA_SMP_GNT_ST_0) \
+_op_(ARB_SEMA_SMP_GET_0) \
+_op_(ARB_SEMA_SMP_PUT_0) \
+_op_(ARB_SEMA_SMP_REQ_ST_0)
+
+
+//
+// ADDRESS SPACES
+//
+
+#define BASE_ADDRESS_ARB_SEMA 0x00000000
+
+//
+// ARARB_SEMA REGISTER BANKS
+//
+
+#define ARB_SEMA0_FIRST_REG 0x0000 // ARB_SEMA_SMP_GNT_ST_0
+#define ARB_SEMA0_LAST_REG 0x000c // ARB_SEMA_SMP_REQ_ST_0
+
+#ifndef _MK_SHIFT_CONST
+ #define _MK_SHIFT_CONST(_constant_) _constant_
+#endif
+#ifndef _MK_MASK_CONST
+ #define _MK_MASK_CONST(_constant_) _constant_
+#endif
+#ifndef _MK_ENUM_CONST
+ #define _MK_ENUM_CONST(_constant_) (_constant_ ## UL)
+#endif
+#ifndef _MK_ADDR_CONST
+ #define _MK_ADDR_CONST(_constant_) _constant_
+#endif
+
+#endif // ifndef ___ARARB_SEMA_H_INC_
diff --git a/arch/arm/mach-tegra/include/ap15/arictlr_arbgnt.h b/arch/arm/mach-tegra/include/ap15/arictlr_arbgnt.h
new file mode 100644
index 000000000000..2d9790b7cc58
--- /dev/null
+++ b/arch/arm/mach-tegra/include/ap15/arictlr_arbgnt.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+//
+// DO NOT EDIT - generated by simspec!
+//
+
+#ifndef ___ARICTLR_ARBGNT_H_INC_
+#define ___ARICTLR_ARBGNT_H_INC_
+//
+// this spec file is for sw header generation
+//
+// hw should use headers generated from:
+// arintr_ctlr.spec
+//
+//
+// arb_gnt specific interrupt controller registers
+//
+// Arbitration semaphores provide a mechanism by which the two processors can arbitrate
+// for the use of various resources. These semaphores provide a hardware locking mechanism,
+// so that when a processor is already using a resource, the second processor is not
+// granted that resource. There are 32 bits of Arbitration semaphores provided in the system.
+// The hardware does not enforce any resource association to these bits. It is left to the
+// firmware to assign and use these bits.
+// The setup/usage of the Arbitration Semaphores is described in the ararb_sema specfile.
+//
+// The Arbitration Semaphores can also generate an interrupt when a hardware resource
+// becomes available. The registers in this module configure these interrupts.
+// When a 1 is set in the corresponding bit position of the Arbitration Semaphore Interrupt
+// Source Register (CPU_enable or COP_enable), an interrupt will be generated when the
+// processor achieves Grant Status for that resource.
+// The current Grant status can be viewed in the CPU_STATUS or COP_STATUS registers.
+//
+// CPU Arbitration Semaphore Interrupt Status Register
+
+// Register ARBGNT_CPU_STATUS_0
+#define ARBGNT_CPU_STATUS_0 _MK_ADDR_CONST(0x0)
+#define ARBGNT_CPU_STATUS_0_WORD_COUNT 0x1
+#define ARBGNT_CPU_STATUS_0_RESET_VAL _MK_MASK_CONST(0x0)
+#define ARBGNT_CPU_STATUS_0_RESET_MASK _MK_MASK_CONST(0xffffffff)
+#define ARBGNT_CPU_STATUS_0_SW_DEFAULT_VAL _MK_MASK_CONST(0x0)
+#define ARBGNT_CPU_STATUS_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+#define ARBGNT_CPU_STATUS_0_READ_MASK _MK_MASK_CONST(0xffffffff)
+#define ARBGNT_CPU_STATUS_0_WRITE_MASK _MK_MASK_CONST(0x0)
+// Each bit is set by hardware when the corresponding arbitration semaphore ownership is granted to CPU. Interrupt is cleared when the CPU writes the ARB_SMP.PUT register with the corresponding bit set.
+#define ARBGNT_CPU_STATUS_0_GNT31_GNG0_SHIFT _MK_SHIFT_CONST(0)
+#define ARBGNT_CPU_STATUS_0_GNT31_GNG0_FIELD (_MK_MASK_CONST(0xffffffff) << ARBGNT_CPU_STATUS_0_GNT31_GNG0_SHIFT)
+#define ARBGNT_CPU_STATUS_0_GNT31_GNG0_RANGE 31:0
+#define ARBGNT_CPU_STATUS_0_GNT31_GNG0_WOFFSET 0x0
+#define ARBGNT_CPU_STATUS_0_GNT31_GNG0_DEFAULT _MK_MASK_CONST(0x0)
+#define ARBGNT_CPU_STATUS_0_GNT31_GNG0_DEFAULT_MASK _MK_MASK_CONST(0xffffffff)
+#define ARBGNT_CPU_STATUS_0_GNT31_GNG0_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define ARBGNT_CPU_STATUS_0_GNT31_GNG0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+
+// CPU Arbitration Semaphore Interrupt Enable Register
+
+// Register ARBGNT_CPU_ENABLE_0
+#define ARBGNT_CPU_ENABLE_0 _MK_ADDR_CONST(0x4)
+#define ARBGNT_CPU_ENABLE_0_WORD_COUNT 0x1
+#define ARBGNT_CPU_ENABLE_0_RESET_VAL _MK_MASK_CONST(0x0)
+#define ARBGNT_CPU_ENABLE_0_RESET_MASK _MK_MASK_CONST(0xffffffff)
+#define ARBGNT_CPU_ENABLE_0_SW_DEFAULT_VAL _MK_MASK_CONST(0x0)
+#define ARBGNT_CPU_ENABLE_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+#define ARBGNT_CPU_ENABLE_0_READ_MASK _MK_MASK_CONST(0xffffffff)
+#define ARBGNT_CPU_ENABLE_0_WRITE_MASK _MK_MASK_CONST(0xffffffff)
+// Writing a 1 in any bit position will enable the corresponding arbitration semaphore interrupt.
+#define ARBGNT_CPU_ENABLE_0_GER31_GER0_SHIFT _MK_SHIFT_CONST(0)
+#define ARBGNT_CPU_ENABLE_0_GER31_GER0_FIELD (_MK_MASK_CONST(0xffffffff) << ARBGNT_CPU_ENABLE_0_GER31_GER0_SHIFT)
+#define ARBGNT_CPU_ENABLE_0_GER31_GER0_RANGE 31:0
+#define ARBGNT_CPU_ENABLE_0_GER31_GER0_WOFFSET 0x0
+#define ARBGNT_CPU_ENABLE_0_GER31_GER0_DEFAULT _MK_MASK_CONST(0x0)
+#define ARBGNT_CPU_ENABLE_0_GER31_GER0_DEFAULT_MASK _MK_MASK_CONST(0xffffffff)
+#define ARBGNT_CPU_ENABLE_0_GER31_GER0_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define ARBGNT_CPU_ENABLE_0_GER31_GER0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+
+// COP Arbitration Semaphore Interrupt Status Register
+
+// Register ARBGNT_COP_STATUS_0
+#define ARBGNT_COP_STATUS_0 _MK_ADDR_CONST(0x8)
+#define ARBGNT_COP_STATUS_0_WORD_COUNT 0x1
+#define ARBGNT_COP_STATUS_0_RESET_VAL _MK_MASK_CONST(0x0)
+#define ARBGNT_COP_STATUS_0_RESET_MASK _MK_MASK_CONST(0xffffffff)
+#define ARBGNT_COP_STATUS_0_SW_DEFAULT_VAL _MK_MASK_CONST(0x0)
+#define ARBGNT_COP_STATUS_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+#define ARBGNT_COP_STATUS_0_READ_MASK _MK_MASK_CONST(0xffffffff)
+#define ARBGNT_COP_STATUS_0_WRITE_MASK _MK_MASK_CONST(0x0)
+// Each bit is set by hardware when the corresponding arbitration semaphore ownership is granted to COP. Interrupt is cleared when the COP writes the ARB_SMP.PUT register with the corresponding bit set.
+#define ARBGNT_COP_STATUS_0_GNT31_GNG0_SHIFT _MK_SHIFT_CONST(0)
+#define ARBGNT_COP_STATUS_0_GNT31_GNG0_FIELD (_MK_MASK_CONST(0xffffffff) << ARBGNT_COP_STATUS_0_GNT31_GNG0_SHIFT)
+#define ARBGNT_COP_STATUS_0_GNT31_GNG0_RANGE 31:0
+#define ARBGNT_COP_STATUS_0_GNT31_GNG0_WOFFSET 0x0
+#define ARBGNT_COP_STATUS_0_GNT31_GNG0_DEFAULT _MK_MASK_CONST(0x0)
+#define ARBGNT_COP_STATUS_0_GNT31_GNG0_DEFAULT_MASK _MK_MASK_CONST(0xffffffff)
+#define ARBGNT_COP_STATUS_0_GNT31_GNG0_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define ARBGNT_COP_STATUS_0_GNT31_GNG0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+
+// COP Arbitration Semaphore Interrupt Enable Register
+
+// Register ARBGNT_COP_ENABLE_0
+#define ARBGNT_COP_ENABLE_0 _MK_ADDR_CONST(0xc)
+#define ARBGNT_COP_ENABLE_0_WORD_COUNT 0x1
+#define ARBGNT_COP_ENABLE_0_RESET_VAL _MK_MASK_CONST(0x0)
+#define ARBGNT_COP_ENABLE_0_RESET_MASK _MK_MASK_CONST(0xffffffff)
+#define ARBGNT_COP_ENABLE_0_SW_DEFAULT_VAL _MK_MASK_CONST(0x0)
+#define ARBGNT_COP_ENABLE_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+#define ARBGNT_COP_ENABLE_0_READ_MASK _MK_MASK_CONST(0xffffffff)
+#define ARBGNT_COP_ENABLE_0_WRITE_MASK _MK_MASK_CONST(0xffffffff)
+// Writing a 1 in any bit position will enable the corresponding arbitration semaphore interrupt.
+#define ARBGNT_COP_ENABLE_0_GER31_GER0_SHIFT _MK_SHIFT_CONST(0)
+#define ARBGNT_COP_ENABLE_0_GER31_GER0_FIELD (_MK_MASK_CONST(0xffffffff) << ARBGNT_COP_ENABLE_0_GER31_GER0_SHIFT)
+#define ARBGNT_COP_ENABLE_0_GER31_GER0_RANGE 31:0
+#define ARBGNT_COP_ENABLE_0_GER31_GER0_WOFFSET 0x0
+#define ARBGNT_COP_ENABLE_0_GER31_GER0_DEFAULT _MK_MASK_CONST(0x0)
+#define ARBGNT_COP_ENABLE_0_GER31_GER0_DEFAULT_MASK _MK_MASK_CONST(0xffffffff)
+#define ARBGNT_COP_ENABLE_0_GER31_GER0_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define ARBGNT_COP_ENABLE_0_GER31_GER0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+
+
+//
+// REGISTER LIST
+//
+#define LIST_ARICTLR_ARBGNT_REGS(_op_) \
+_op_(ARBGNT_CPU_STATUS_0) \
+_op_(ARBGNT_CPU_ENABLE_0) \
+_op_(ARBGNT_COP_STATUS_0) \
+_op_(ARBGNT_COP_ENABLE_0)
+
+
+//
+// ADDRESS SPACES
+//
+
+#define BASE_ADDRESS_ARBGNT 0x00000000
+
+//
+// ARICTLR_ARBGNT REGISTER BANKS
+//
+
+#define ARBGNT0_FIRST_REG 0x0000 // ARBGNT_CPU_STATUS_0
+#define ARBGNT0_LAST_REG 0x000c // ARBGNT_COP_ENABLE_0
+
+#ifndef _MK_SHIFT_CONST
+ #define _MK_SHIFT_CONST(_constant_) _constant_
+#endif
+#ifndef _MK_MASK_CONST
+ #define _MK_MASK_CONST(_constant_) _constant_
+#endif
+#ifndef _MK_ENUM_CONST
+ #define _MK_ENUM_CONST(_constant_) (_constant_ ## UL)
+#endif
+#ifndef _MK_ADDR_CONST
+ #define _MK_ADDR_CONST(_constant_) _constant_
+#endif
+
+#endif // ifndef ___ARICTLR_ARBGNT_H_INC_
diff --git a/arch/arm/mach-tegra/include/ap15/arres_sema.h b/arch/arm/mach-tegra/include/ap15/arres_sema.h
new file mode 100644
index 000000000000..093439d20511
--- /dev/null
+++ b/arch/arm/mach-tegra/include/ap15/arres_sema.h
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+//
+// DO NOT EDIT - generated by simspec!
+//
+
+#ifndef ___ARRES_SEMA_H_INC_
+#define ___ARRES_SEMA_H_INC_
+// Shared Resource Semaphore Status
+
+// Register RES_SEMA_SHRD_SMP_STA_0
+#define RES_SEMA_SHRD_SMP_STA_0 _MK_ADDR_CONST(0x0)
+#define RES_SEMA_SHRD_SMP_STA_0_WORD_COUNT 0x1
+#define RES_SEMA_SHRD_SMP_STA_0_RESET_VAL _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_SMP_STA_0_RESET_MASK _MK_MASK_CONST(0xffffffff)
+#define RES_SEMA_SHRD_SMP_STA_0_SW_DEFAULT_VAL _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_SMP_STA_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_SMP_STA_0_READ_MASK _MK_MASK_CONST(0xffffffff)
+#define RES_SEMA_SHRD_SMP_STA_0_WRITE_MASK _MK_MASK_CONST(0x0)
+// SMP.27:SMP.24: Available in APB_DMA.REQUESTORS register
+#define RES_SEMA_SHRD_SMP_STA_0_SMP_31_SMP_0_SHIFT _MK_SHIFT_CONST(0)
+#define RES_SEMA_SHRD_SMP_STA_0_SMP_31_SMP_0_FIELD (_MK_MASK_CONST(0xffffffff) << RES_SEMA_SHRD_SMP_STA_0_SMP_31_SMP_0_SHIFT)
+#define RES_SEMA_SHRD_SMP_STA_0_SMP_31_SMP_0_RANGE 31:0
+#define RES_SEMA_SHRD_SMP_STA_0_SMP_31_SMP_0_WOFFSET 0x0
+#define RES_SEMA_SHRD_SMP_STA_0_SMP_31_SMP_0_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_SMP_STA_0_SMP_31_SMP_0_DEFAULT_MASK _MK_MASK_CONST(0xffffffff)
+#define RES_SEMA_SHRD_SMP_STA_0_SMP_31_SMP_0_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_SMP_STA_0_SMP_31_SMP_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+
+// Shared Resource Semaphore Set-bit Request
+
+// Register RES_SEMA_SHRD_SMP_SET_0
+#define RES_SEMA_SHRD_SMP_SET_0 _MK_ADDR_CONST(0x4)
+#define RES_SEMA_SHRD_SMP_SET_0_WORD_COUNT 0x1
+#define RES_SEMA_SHRD_SMP_SET_0_RESET_VAL _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_SMP_SET_0_RESET_MASK _MK_MASK_CONST(0xffffffff)
+#define RES_SEMA_SHRD_SMP_SET_0_SW_DEFAULT_VAL _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_SMP_SET_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_SMP_SET_0_READ_MASK _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_SMP_SET_0_WRITE_MASK _MK_MASK_CONST(0xffffffff)
+// Semaphore set register. Writing a one to any bit will set the corresponding semaphore bit. Shared resource set-bit requests
+#define RES_SEMA_SHRD_SMP_SET_0_SET_31_SET_0_SHIFT _MK_SHIFT_CONST(0)
+#define RES_SEMA_SHRD_SMP_SET_0_SET_31_SET_0_FIELD (_MK_MASK_CONST(0xffffffff) << RES_SEMA_SHRD_SMP_SET_0_SET_31_SET_0_SHIFT)
+#define RES_SEMA_SHRD_SMP_SET_0_SET_31_SET_0_RANGE 31:0
+#define RES_SEMA_SHRD_SMP_SET_0_SET_31_SET_0_WOFFSET 0x0
+#define RES_SEMA_SHRD_SMP_SET_0_SET_31_SET_0_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_SMP_SET_0_SET_31_SET_0_DEFAULT_MASK _MK_MASK_CONST(0xffffffff)
+#define RES_SEMA_SHRD_SMP_SET_0_SET_31_SET_0_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_SMP_SET_0_SET_31_SET_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+
+// Shared Resource Semaphore Clr-bit Request Register
+
+// Register RES_SEMA_SHRD_SMP_CLR_0
+#define RES_SEMA_SHRD_SMP_CLR_0 _MK_ADDR_CONST(0x8)
+#define RES_SEMA_SHRD_SMP_CLR_0_WORD_COUNT 0x1
+#define RES_SEMA_SHRD_SMP_CLR_0_RESET_VAL _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_SMP_CLR_0_RESET_MASK _MK_MASK_CONST(0xffffffff)
+#define RES_SEMA_SHRD_SMP_CLR_0_SW_DEFAULT_VAL _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_SMP_CLR_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_SMP_CLR_0_READ_MASK _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_SMP_CLR_0_WRITE_MASK _MK_MASK_CONST(0x0)
+// corresponding semaphore bit
+#define RES_SEMA_SHRD_SMP_CLR_0_CLR_31_CLR_0_SHIFT _MK_SHIFT_CONST(0)
+#define RES_SEMA_SHRD_SMP_CLR_0_CLR_31_CLR_0_FIELD (_MK_MASK_CONST(0xffffffff) << RES_SEMA_SHRD_SMP_CLR_0_CLR_31_CLR_0_SHIFT)
+#define RES_SEMA_SHRD_SMP_CLR_0_CLR_31_CLR_0_RANGE 31:0
+#define RES_SEMA_SHRD_SMP_CLR_0_CLR_31_CLR_0_WOFFSET 0x0
+#define RES_SEMA_SHRD_SMP_CLR_0_CLR_31_CLR_0_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_SMP_CLR_0_CLR_31_CLR_0_DEFAULT_MASK _MK_MASK_CONST(0xffffffff)
+#define RES_SEMA_SHRD_SMP_CLR_0_CLR_31_CLR_0_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_SMP_CLR_0_CLR_31_CLR_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+
+
+// Reserved address 12 [0xc]
+// Shared Resource Inbox (messages from COP to CPU)
+
+// Register RES_SEMA_SHRD_INBOX_0
+#define RES_SEMA_SHRD_INBOX_0 _MK_ADDR_CONST(0x10)
+#define RES_SEMA_SHRD_INBOX_0_WORD_COUNT 0x1
+#define RES_SEMA_SHRD_INBOX_0_RESET_VAL _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_RESET_MASK _MK_MASK_CONST(0xffffffff)
+#define RES_SEMA_SHRD_INBOX_0_SW_DEFAULT_VAL _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_READ_MASK _MK_MASK_CONST(0xffffffff)
+#define RES_SEMA_SHRD_INBOX_0_WRITE_MASK _MK_MASK_CONST(0x0)
+// Interrupt CPU on INBOX Full (TAG=1)
+#define RES_SEMA_SHRD_INBOX_0_IE_IBF_SHIFT _MK_SHIFT_CONST(31)
+#define RES_SEMA_SHRD_INBOX_0_IE_IBF_FIELD (_MK_MASK_CONST(0x1) << RES_SEMA_SHRD_INBOX_0_IE_IBF_SHIFT)
+#define RES_SEMA_SHRD_INBOX_0_IE_IBF_RANGE 31:31
+#define RES_SEMA_SHRD_INBOX_0_IE_IBF_WOFFSET 0x0
+#define RES_SEMA_SHRD_INBOX_0_IE_IBF_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_IE_IBF_DEFAULT_MASK _MK_MASK_CONST(0x1)
+#define RES_SEMA_SHRD_INBOX_0_IE_IBF_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_IE_IBF_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_IE_IBF_EMPTY _MK_ENUM_CONST(0)
+#define RES_SEMA_SHRD_INBOX_0_IE_IBF_FULL _MK_ENUM_CONST(1)
+
+// Interrupt COP on INBOX Empty (TAG=0)
+#define RES_SEMA_SHRD_INBOX_0_IE_IBE_SHIFT _MK_SHIFT_CONST(30)
+#define RES_SEMA_SHRD_INBOX_0_IE_IBE_FIELD (_MK_MASK_CONST(0x1) << RES_SEMA_SHRD_INBOX_0_IE_IBE_SHIFT)
+#define RES_SEMA_SHRD_INBOX_0_IE_IBE_RANGE 30:30
+#define RES_SEMA_SHRD_INBOX_0_IE_IBE_WOFFSET 0x0
+#define RES_SEMA_SHRD_INBOX_0_IE_IBE_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_IE_IBE_DEFAULT_MASK _MK_MASK_CONST(0x1)
+#define RES_SEMA_SHRD_INBOX_0_IE_IBE_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_IE_IBE_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_IE_IBE_EMPTY _MK_ENUM_CONST(0)
+#define RES_SEMA_SHRD_INBOX_0_IE_IBE_FULL _MK_ENUM_CONST(1)
+
+// Read-only. Set when COP writes this register and cleared when CPU Reads this register.
+#define RES_SEMA_SHRD_INBOX_0_TAG_SHIFT _MK_SHIFT_CONST(29)
+#define RES_SEMA_SHRD_INBOX_0_TAG_FIELD (_MK_MASK_CONST(0x1) << RES_SEMA_SHRD_INBOX_0_TAG_SHIFT)
+#define RES_SEMA_SHRD_INBOX_0_TAG_RANGE 29:29
+#define RES_SEMA_SHRD_INBOX_0_TAG_WOFFSET 0x0
+#define RES_SEMA_SHRD_INBOX_0_TAG_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_TAG_DEFAULT_MASK _MK_MASK_CONST(0x1)
+#define RES_SEMA_SHRD_INBOX_0_TAG_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_TAG_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_TAG_INVALID _MK_ENUM_CONST(0)
+#define RES_SEMA_SHRD_INBOX_0_TAG_VALID _MK_ENUM_CONST(1)
+
+// Reserved = 0
+#define RES_SEMA_SHRD_INBOX_0_N_A1_SHIFT _MK_SHIFT_CONST(28)
+#define RES_SEMA_SHRD_INBOX_0_N_A1_FIELD (_MK_MASK_CONST(0x1) << RES_SEMA_SHRD_INBOX_0_N_A1_SHIFT)
+#define RES_SEMA_SHRD_INBOX_0_N_A1_RANGE 28:28
+#define RES_SEMA_SHRD_INBOX_0_N_A1_WOFFSET 0x0
+#define RES_SEMA_SHRD_INBOX_0_N_A1_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_N_A1_DEFAULT_MASK _MK_MASK_CONST(0x1)
+#define RES_SEMA_SHRD_INBOX_0_N_A1_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_N_A1_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+
+// definition)
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_STAT_SHIFT _MK_SHIFT_CONST(24)
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_STAT_FIELD (_MK_MASK_CONST(0xf) << RES_SEMA_SHRD_INBOX_0_IN_BOX_STAT_SHIFT)
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_STAT_RANGE 27:24
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_STAT_WOFFSET 0x0
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_STAT_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_STAT_DEFAULT_MASK _MK_MASK_CONST(0xf)
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_STAT_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_STAT_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+
+// General purpose data bits, suggested usage is for INBOX command (SW can change definition)
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_CMD_SHIFT _MK_SHIFT_CONST(17)
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_CMD_FIELD (_MK_MASK_CONST(0x7f) << RES_SEMA_SHRD_INBOX_0_IN_BOX_CMD_SHIFT)
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_CMD_RANGE 23:17
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_CMD_WOFFSET 0x0
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_CMD_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_CMD_DEFAULT_MASK _MK_MASK_CONST(0x7f)
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_CMD_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_CMD_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+
+// definition)
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_DATA_SHIFT _MK_SHIFT_CONST(0)
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_DATA_FIELD (_MK_MASK_CONST(0x1ffff) << RES_SEMA_SHRD_INBOX_0_IN_BOX_DATA_SHIFT)
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_DATA_RANGE 16:0
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_DATA_WOFFSET 0x0
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_DATA_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_DATA_DEFAULT_MASK _MK_MASK_CONST(0x1ffff)
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_DATA_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_INBOX_0_IN_BOX_DATA_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+
+
+// Reserved address 20 [0x14]
+
+// Reserved address 24 [0x18]
+
+// Reserved address 28 [0x1c]
+// Shared Resource Outbox (messages from CPU to COP)
+
+// Register RES_SEMA_SHRD_OUTBOX_0
+#define RES_SEMA_SHRD_OUTBOX_0 _MK_ADDR_CONST(0x20)
+#define RES_SEMA_SHRD_OUTBOX_0_WORD_COUNT 0x1
+#define RES_SEMA_SHRD_OUTBOX_0_RESET_VAL _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_RESET_MASK _MK_MASK_CONST(0xffffffff)
+#define RES_SEMA_SHRD_OUTBOX_0_SW_DEFAULT_VAL _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_READ_MASK _MK_MASK_CONST(0xffffffff)
+#define RES_SEMA_SHRD_OUTBOX_0_WRITE_MASK _MK_MASK_CONST(0x0)
+// Interrupt COP on OUTBOX Full (TAG=1)
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBF_SHIFT _MK_SHIFT_CONST(31)
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBF_FIELD (_MK_MASK_CONST(0x1) << RES_SEMA_SHRD_OUTBOX_0_IE_OBF_SHIFT)
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBF_RANGE 31:31
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBF_WOFFSET 0x0
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBF_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBF_DEFAULT_MASK _MK_MASK_CONST(0x1)
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBF_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBF_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBF_EMPTY _MK_ENUM_CONST(0)
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBF_FULL _MK_ENUM_CONST(1)
+
+// Interrupt CPU on OUTBOX Empty (TAG=0)
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBE_SHIFT _MK_SHIFT_CONST(30)
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBE_FIELD (_MK_MASK_CONST(0x1) << RES_SEMA_SHRD_OUTBOX_0_IE_OBE_SHIFT)
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBE_RANGE 30:30
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBE_WOFFSET 0x0
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBE_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBE_DEFAULT_MASK _MK_MASK_CONST(0x1)
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBE_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBE_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBE_EMPTY _MK_ENUM_CONST(0)
+#define RES_SEMA_SHRD_OUTBOX_0_IE_OBE_FULL _MK_ENUM_CONST(1)
+
+// HW clears this bit when COP Reads the Outbox Register. Read-only. Set when CPU writes this register and cleared when COP reads this register.
+#define RES_SEMA_SHRD_OUTBOX_0_TAG_SHIFT _MK_SHIFT_CONST(29)
+#define RES_SEMA_SHRD_OUTBOX_0_TAG_FIELD (_MK_MASK_CONST(0x1) << RES_SEMA_SHRD_OUTBOX_0_TAG_SHIFT)
+#define RES_SEMA_SHRD_OUTBOX_0_TAG_RANGE 29:29
+#define RES_SEMA_SHRD_OUTBOX_0_TAG_WOFFSET 0x0
+#define RES_SEMA_SHRD_OUTBOX_0_TAG_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_TAG_DEFAULT_MASK _MK_MASK_CONST(0x1)
+#define RES_SEMA_SHRD_OUTBOX_0_TAG_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_TAG_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_TAG_INVALID _MK_ENUM_CONST(0)
+#define RES_SEMA_SHRD_OUTBOX_0_TAG_VALID _MK_ENUM_CONST(1)
+
+// Reserved = 0
+#define RES_SEMA_SHRD_OUTBOX_0_N_A1_SHIFT _MK_SHIFT_CONST(28)
+#define RES_SEMA_SHRD_OUTBOX_0_N_A1_FIELD (_MK_MASK_CONST(0x1) << RES_SEMA_SHRD_OUTBOX_0_N_A1_SHIFT)
+#define RES_SEMA_SHRD_OUTBOX_0_N_A1_RANGE 28:28
+#define RES_SEMA_SHRD_OUTBOX_0_N_A1_WOFFSET 0x0
+#define RES_SEMA_SHRD_OUTBOX_0_N_A1_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_N_A1_DEFAULT_MASK _MK_MASK_CONST(0x1)
+#define RES_SEMA_SHRD_OUTBOX_0_N_A1_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_N_A1_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+
+// General purpose data bits, suggested usage is for Out Box OUTBOX status (SW can change definition)
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_STAT_SHIFT _MK_SHIFT_CONST(24)
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_STAT_FIELD (_MK_MASK_CONST(0xf) << RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_STAT_SHIFT)
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_STAT_RANGE 27:24
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_STAT_WOFFSET 0x0
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_STAT_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_STAT_DEFAULT_MASK _MK_MASK_CONST(0xf)
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_STAT_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_STAT_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+
+// General purpose data bits, suggested usage is for Out Box OUTBOX command (SW can change definition)
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_CMD_SHIFT _MK_SHIFT_CONST(17)
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_CMD_FIELD (_MK_MASK_CONST(0x7f) << RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_CMD_SHIFT)
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_CMD_RANGE 23:17
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_CMD_WOFFSET 0x0
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_CMD_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_CMD_DEFAULT_MASK _MK_MASK_CONST(0x7f)
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_CMD_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_CMD_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+
+// General purpose Out Box data bits, suggested usage is for OUTBOX data (SW can change definition)
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_DATA_SHIFT _MK_SHIFT_CONST(0)
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_DATA_FIELD (_MK_MASK_CONST(0x1ffff) << RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_DATA_SHIFT)
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_DATA_RANGE 16:0
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_DATA_WOFFSET 0x0
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_DATA_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_DATA_DEFAULT_MASK _MK_MASK_CONST(0x1ffff)
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_DATA_SW_DEFAULT _MK_MASK_CONST(0x0)
+#define RES_SEMA_SHRD_OUTBOX_0_OUT_BOX_DATA_SW_DEFAULT_MASK _MK_MASK_CONST(0x0)
+
+
+//
+// REGISTER LIST
+//
+#define LIST_ARRES_SEMA_REGS(_op_) \
+_op_(RES_SEMA_SHRD_SMP_STA_0) \
+_op_(RES_SEMA_SHRD_SMP_SET_0) \
+_op_(RES_SEMA_SHRD_SMP_CLR_0) \
+_op_(RES_SEMA_SHRD_INBOX_0) \
+_op_(RES_SEMA_SHRD_OUTBOX_0)
+
+
+//
+// ADDRESS SPACES
+//
+
+#define BASE_ADDRESS_RES_SEMA 0x00000000
+
+//
+// ARRES_SEMA REGISTER BANKS
+//
+
+#define RES_SEMA0_FIRST_REG 0x0000 // RES_SEMA_SHRD_SMP_STA_0
+#define RES_SEMA0_LAST_REG 0x0008 // RES_SEMA_SHRD_SMP_CLR_0
+#define RES_SEMA1_FIRST_REG 0x0010 // RES_SEMA_SHRD_INBOX_0
+#define RES_SEMA1_LAST_REG 0x0010 // RES_SEMA_SHRD_INBOX_0
+#define RES_SEMA2_FIRST_REG 0x0020 // RES_SEMA_SHRD_OUTBOX_0
+#define RES_SEMA2_LAST_REG 0x0020 // RES_SEMA_SHRD_OUTBOX_0
+
+#ifndef _MK_SHIFT_CONST
+ #define _MK_SHIFT_CONST(_constant_) _constant_
+#endif
+#ifndef _MK_MASK_CONST
+ #define _MK_MASK_CONST(_constant_) _constant_
+#endif
+#ifndef _MK_ENUM_CONST
+ #define _MK_ENUM_CONST(_constant_) (_constant_ ## UL)
+#endif
+#ifndef _MK_ADDR_CONST
+ #define _MK_ADDR_CONST(_constant_) _constant_
+#endif
+
+#endif // ifndef ___ARRES_SEMA_H_INC_
diff --git a/arch/arm/mach-tegra/include/avp.h b/arch/arm/mach-tegra/include/avp.h
new file mode 100644
index 000000000000..249a28cd44db
--- /dev/null
+++ b/arch/arm/mach-tegra/include/avp.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_AVP_H
+#define INCLUDED_AVP_H
+
+#include "ap15/arictlr.h"
+#include "ap15/artimer.h"
+// FIXME: get the ararmev header
+
+// 3 controllers in contiguous memory starting at INTERRUPT_BASE, each
+// controller's aperture is INTERRUPT_SIZE large
+#define INTERRUPT_BASE 0x60004000
+#define INTERRUPT_SIZE 0x100
+#define INTERRUPT_NUM_CONTROLLERS 3
+
+#define INTERRUPT_PENDING( ctlr ) \
+ (INTERRUPT_BASE + ((ctlr) * INTERRUPT_SIZE) + ICTLR_VIRQ_COP_0)
+
+#define INTERRUPT_SET( ctlr ) \
+ (INTERRUPT_BASE + ((ctlr) * INTERRUPT_SIZE) + ICTLR_COP_IER_SET_0)
+
+#define INTERRUPT_CLR( ctlr ) \
+ (INTERRUPT_BASE + ((ctlr) * INTERRUPT_SIZE) + ICTLR_COP_IER_CLR_0)
+
+#define OSC_CTRL ( 0x60006000 + 0x50 )
+#define OSC_FREQ_DET ( 0x60006000 + 0x58 )
+#define OSC_DET_STATUS ( 0x60006000 + 0x5C )
+
+#define TIMER_USEC ( 0x60005010 )
+#define TIMER_CFG ( 0x60005014 )
+#define TIMER_0_BASE ( 0x60005000 )
+#define TIMER_0 ( TIMER_0_BASE + TIMER_TMR_PTV_0 )
+#define TIMER_0_CLEAR ( TIMER_0_BASE + TIMER_TMR_PCR_0 )
+#define TIMER_1_BASE ( 0x60005008 )
+#define TIMER_1 ( TIMER_1_BASE + TIMER_TMR_PTV_0 )
+#define TIMER_1_CLEAR ( TIMER_1_BASE + TIMER_TMR_PCR_0 )
+
+#define CLOCK_RST_LO (0x60006004)
+#define CLOCK_CTLR_HI (0x60006014)
+#define CLOCK_CTLR_LO (0x60006010)
+
+#define CACHE_CTLR (0x6000C000)
+#define CACHE_CONTROL_0 (0x0)
+
+#define PPI_INTR_ID_TIMER_0 (0)
+#define PPI_INTR_ID_TIMER_1 (1)
+#define PPI_INTR_ID_TIMER_2 (9)
+#define PPI_INTR_ID_TIMER_3 (10)
+
+/* flow controller */
+#define FLOW_CONTROLLER (0x60007004)
+
+/* exception vectors */
+#define VECTOR_BASE ( 0x6000F200 )
+#define VECTOR_RESET ( VECTOR_BASE + 0 )
+#define VECTOR_UNDEF ( VECTOR_BASE + 4 )
+#define VECTOR_SWI ( VECTOR_BASE + 8 )
+#define VECTOR_PREFETCH_ABORT ( VECTOR_BASE + 12 )
+#define VECTOR_DATA_ABORT ( VECTOR_BASE + 16 )
+#define VECTOR_IRQ ( VECTOR_BASE + 24 )
+#define VECTOR_FIQ ( VECTOR_BASE + 28 )
+
+#define MODE_DISABLE_INTR 0xc0
+#define MODE_USR 0x10
+#define MODE_FIQ 0x11
+#define MODE_IRQ 0x12
+#define MODE_SVC 0x13
+#define MODE_ABT 0x17
+#define MODE_UND 0x1B
+#define MODE_SYS 0x1F
+
+#define AP15_CACHE_LINE_SIZE 32
+
+#define AP15_APB_L2_CACHE_BASE 0x7000e800
+#define AP15_APB_CLK_RST_BASE 0x60006000
+#define AP15_APB_MISC_BASE 0x70000000
+
+#define AP10_APB_CLK_RST_BASE 0x60006000
+#define AP10_APB_MISC_BASE 0x70000000
+
+#define MMU_TLB_BASE 0xf000f000
+#define MMU_TLB_CACHE_WINDOW_0 0x40
+#define MMU_TLB_CACHE_OPTIONS_0 0x44
+
+#define AP15_PINMUX_CFG_CTL_0 0x70000024
+#define AP15_AVP_JTAG_ENABLE 0xC0
+
+#define PMC_SCRATCH22_REG_LP0 0x7000e4a8
+
+#define AVP_WDT_RESET 0x2F00BAD0
+
+/* Cached to uncached offset for AVP
+ *
+ * Hardware has uncached remap aperture for AVP as AVP doesn't have MMU
+ * but still has cache (named COP cache).
+ *
+ * This aperture moved between AP15 and AP20.
+ */
+#define AP15_CACHED_TO_UNCACHED_OFFSET 0x90000000
+#define AP20_CACHED_TO_UNCACHED_OFFSET 0x80000000
+
+#define APXX_EXT_MEM_START 0x00000000
+#define APXX_EXT_MEM_END 0x40000000
+
+#define APXX_MMIO_START 0x40000000
+#define APXX_MMIO_END 0xFFF00000
+
+#define TXX_EXT_MEM_START 0x80000000
+#define TXX_EXT_MEM_END 0xc0000000
+
+#define TXX_MMIO_START 0x40000000
+#define TXX_MMIO_END 0x80000000
+
+#endif
diff --git a/arch/arm/mach-tegra/include/nvrm_avp_shrd_interrupt.h b/arch/arm/mach-tegra/include/nvrm_avp_shrd_interrupt.h
new file mode 100644
index 000000000000..579aab3c240d
--- /dev/null
+++ b/arch/arm/mach-tegra/include/nvrm_avp_shrd_interrupt.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_nvrm_avp_shrd_interrupt_H
+#define INCLUDED_nvrm_avp_shrd_interrupt_H
+
+#include "nvos.h"
+#include "nvrm_init.h"
+#include "nvrm_module.h"
+#include "nvrm_interrupt.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* Max number of clients with shared interrupt handler */
+enum {MAX_SHRDINT_CLIENTS = 32};
+
+/* Now AP15 support only VDE interrupts 6 */
+enum {MAX_SHRDINT_INTERRUPTS = 6};
+ /* VDE Sync Token Interrupt */
+enum {AP15_SYNC_TOKEN_INTERRUPT_INDEX = 0};
+ /* VDE BSE-V Interrupt */
+enum {AP15_BSE_V_INTERRUPT_INDEX = 1};
+ /* VDE BSE-A Interrupt */
+enum {AP15_BSE_A_INTERRUPT_INDEX = 2};
+ /* VDE SXE Interrupt */
+enum {AP15_SXE_INTERRUPT_INDEX = 3};
+ /* VDE UCQ Error Interrupt */
+enum {AP15_UCQ_INTERRUPT_INDEX = 4};
+ /* VDE Interrupt */
+enum {AP15_VDE_INTERRUPT_INDEX = 5};
+
+/* Now AP20 support only VDE interrupts 5 */
+enum {AP20_MAX_SHRDINT_INTERRUPTS = 5};
+ /* VDE Sync Token Interrupt */
+enum {AP20_SYNC_TOKEN_INTERRUPT_INDEX = 0};
+ /* VDE BSE-V Interrupt */
+enum {AP20_BSE_V_INTERRUPT_INDEX = 1};
+ /* VDE SXE Interrupt */
+enum {AP20_SXE_INTERRUPT_INDEX = 2};
+ /* VDE UCQ Error Interrupt */
+enum {AP20_UCQ_INTERRUPT_INDEX = 3};
+ /* VDE Interrupt */
+enum {AP20_VDE_INTERRUPT_INDEX = 4};
+
+enum
+{
+ NvRmArbSema_Vde = 0,
+ NvRmArbSema_Bsea,
+ //This should be last
+ NvRmArbSema_Num,
+};
+
+/* Shared interrupt private init , init done during RM init on AVP */
+NvError NvRmAvpShrdInterruptPrvInit(NvRmDeviceHandle hRmDevice);
+
+/* Shared interrupt private de-init , de-init done during RM close on AVP */
+void NvRmAvpShrdInterruptPrvDeinit(NvRmDeviceHandle hRmDevice);
+
+/* Get logical interrupt for a module*/
+NvU32 NvRmAvpShrdInterruptGetIrqForLogicalInterrupt(NvRmDeviceHandle hRmDevice,
+ NvRmModuleID ModuleID,
+ NvU32 Index);
+/* Register for shared interrpt */
+NvError NvRmAvpShrdInterruptRegister(NvRmDeviceHandle hRmDevice,
+ NvU32 IrqListSize,
+ const NvU32 *pIrqList,
+ const NvOsInterruptHandler *pIrqHandlerList,
+ void *pContext,
+ NvOsInterruptHandle *handle,
+ NvU32 *ClientIndex);
+/* Un-register a shared interrpt */
+void NvRmAvpShrdInterruptUnregister(NvRmDeviceHandle hRmDevice,
+ NvOsInterruptHandle handle,
+ NvU32 ClientIndex);
+/* Get exclisive access to a hardware(VDE) block */
+NvError NvRmAvpShrdInterruptAquireHwBlock(NvRmModuleID ModuleID, NvU32 ClientId);
+
+/* Release exclisive access to a hardware(VDE) block */
+NvError NvRmAvpShrdInterruptReleaseHwBlock(NvRmModuleID ModuleID, NvU32 ClientId);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif //INCLUDED_nvrm_avp_shrd_interrupt_H
diff --git a/arch/arm/mach-tegra/include/nvrm_transport.h b/arch/arm/mach-tegra/include/nvrm_transport.h
new file mode 100644
index 000000000000..179f63223ed5
--- /dev/null
+++ b/arch/arm/mach-tegra/include/nvrm_transport.h
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_nvrm_transport_H
+#define INCLUDED_nvrm_transport_H
+
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+#include "nvrm_module.h"
+#include "nvrm_init.h"
+
+/** @file
+ * @brief <b>NVIDIA Driver Development Kit:
+ * Resource Manager Transport APIs</b>
+ *
+ * @b Description: This is the Transport API, which defines a simple means to
+ * pass messages across a lower level connection (generally between
+ * processors).
+ *
+ */
+
+/** @defgroup nvrm_transport RM Transport API
+ *
+ * The Transport API defines a simple protocol through which clients and
+ * services may connect and communicate--normally, though not necessarily,
+ * across separate processors. Clients to this interface mostly include
+ * audio-visual applications whose code may reside on either the MPCore or AVP
+ * processors. These applications (and there could be many concurrently) may
+ * utilize this transport API to synchronize their operations. How the
+ * Transport API shepherds messages through these connections is not visible to
+ * the client.
+ *
+ * To setup a new connection, both the client and the service must open a port
+ * (whose name is agreed upon before compile-time). The service waits for a
+ * client to connect; this "handshake" allows a connection to be established.
+ * Once a client has established a connection with the service, they may send
+ * and receive messages.
+ *
+ * @ingroup nvddk_rm
+ * @{
+ */
+
+#include "nvos.h"
+
+/**
+ * A type-safe handle for the transport connection.
+ */
+
+typedef struct NvRmTransportRec *NvRmTransportHandle;
+
+/**
+ * Creates one end of a transport connection. Both the service and client
+ * to the service must call this API to create each endpoint of the connection
+ * through a specified port (whose name is agreed upon before compile-time).
+ * A connection is not established between the service and client until a
+ * handshake is completed (via calls to NvRmTransportWaitForConnect() and
+ * NvRmTransportConnect() respectively).
+ *
+ * Assert in debug mode encountered if PortName is too long or does not exist
+ *
+ * @see NvRmTransportWaitForConnect()
+ * @see NvRmTransportConnect()
+ * @see NvRmTransportClose()
+ *
+ * @param hRmDevice Handle to RM device
+ * @param pPortName A character string that identifies the name of the port.
+ * This value must be 16 bytes or less, otherwise the caller receives an error.
+ * You can optionally pass NULL for this parameter, in which case a unique
+ * name will be assigned. And you can call NvRmTransporGetPortName to retrieve
+ * the name.
+ * @param RecvMessageSemaphore The externally created semaphore that the
+ * transport connection will signal upon receipt of a message.
+ * @param phTransport Points to the location where the transport handle shall
+ * be stored
+ *
+ * @retval NvSuccess Transport endpoint successfully allocated
+ * @retval NvError_InsufficientMemory Not enough memory to allocate endpoint
+ * @retval NvError_MutexCreateFailed Creaion of mutex failed.
+ * @retval NvError_SemaphoreCreateFailed Creaion of semaphore failed.
+ * @retval NvError_SharedMemAllocFailed Creaion of shared memory allocation
+ * failed.
+ * @retval NvError_NotInitialized The transport is not able to initialzed the
+ * threads.
+ */
+
+ NvError NvRmTransportOpen(
+ NvRmDeviceHandle hRmDevice,
+ char * pPortName,
+ NvOsSemaphoreHandle RecvMessageSemaphore,
+ NvRmTransportHandle * phTransport );
+
+/**
+ * Retrieve the name associated with a port.
+ *
+ * Assert in debug mode encountered if PortName is too long or does not exist
+ *
+ * @see NvRmTransportOpen()
+ *
+ * @param hTransport Handle to the port that you want the name of.
+ * @param PortName A character string that identifies the name of the port.
+ * @param PortNameSize Length of the PortName buffer.
+ *
+ */
+
+ void NvRmTransportGetPortName(
+ NvRmTransportHandle hTransport,
+ NvU8 * PortName,
+ NvU32 PortNameSize );
+
+/**
+ * Closes a transport connection. Proper closure of this connection requires
+ * that both the client and service call this API. Therefore, it is expected
+ * that the client and service message one another to coordinate the close.
+ *
+ * @see NvRmTransportOpen()
+ *
+ * @param hTransport Specifies the transport connection to close. If hTransport
+ * is NULL, this API does nothing.
+ */
+
+ void NvRmTransportClose(
+ NvRmTransportHandle hTransport );
+
+/**
+ * Initializes the transport.
+ *
+ * @param hRmDevice Handle to RM device
+ *
+ */
+
+ NvError NvRmTransportInit(
+ NvRmDeviceHandle hRmDevice );
+
+/**
+ * Deinitializes the transport.
+ *
+ * @param hRmDevice Handle to RM device
+ *
+ */
+
+ void NvRmTransportDeInit(
+ NvRmDeviceHandle hRmDevice );
+
+/**
+ * This handshake API is called by the service, which waits for a client to
+ * establish a connection via a call to NvRmTransportConnect(). Messages
+ * cannot be sent and received until this handshake is completed.
+ *
+ * To ensure a client has sufficient opportunity to establish a connection
+ * from the other end, a large timeout value (such as NV_WAIT_INFINITE) is
+ * recommended here.
+ *
+ * @see NvRmTransportConnect()
+ *
+ * @param hTransport Specifies the transport connection
+ * @param TimeoutMS Specifies the amount of time (in milliseconds) to wait for
+ * connection to be established. A value of NV_WAIT_INFINITE means "wait
+ * indefinitely." A value of zero (0) will timeout immediately, which is
+ * not recommended for this function call.
+ *
+ * @retval NvSuccess Service is waiting to receive a "connect" from client
+ * @retval NvError_NotInitialized hTransport is not open
+ * @retval NvError_Timeout Timed out waiting for service to respond
+ */
+
+ NvError NvRmTransportWaitForConnect(
+ NvRmTransportHandle hTransport,
+ NvU32 TimeoutMS );
+
+/**
+ * This blocking handshake API is called by the client, which seeks a
+ * service (as specified by a handle) to establish a connection. Messages
+ * cannot be sent and received until this handshake is completed.
+ *
+ * @see NvRmTransportWaitForConnect()
+ *
+ * @param hTransport Specifies the transport connection
+ * @param TimeoutMS Specifies the amount of time (in milliseconds) to wait for
+ * connection to be established. A value of NV_WAIT_INFINITE means "wait
+ * indefinitely." A value of zero (0) will timeout immediately, but
+ * this function will at least take time to check if the port is open and
+ * waiting for a connection--if so, a connection will be established.
+ *
+ * @retval NvSuccess Transport connection successfully established
+ * @retval NvError_NotInitialized hTransport is not open
+ * @retval NvError_Timeout Timed out waiting for service to respond.
+ */
+
+ NvError NvRmTransportConnect(
+ NvRmTransportHandle hTransport,
+ NvU32 TimeoutMS );
+
+/**
+ * Set the max size of the message queue (FIFO) deptha nd length which can be
+ * send and receive from this port. The programmer must decide the
+ * queue depth that's appropriate for their design. If this function is not
+ * called, the queue depth is set to one (1) and message size is 256 bytes.
+ *
+ *
+ * @see NvRmTransportSendMsg()
+ * @see NvRmTransportRecvMsg()
+ *
+ * @param hTransport Specifies the transport connection
+ * @param MaxQueueDepth The maximum number of message which can be queued for
+ * this port for receiving and sending. The receive message can queue message
+ * till this count for this port. If receive queue is full for this port and
+ * if other port send the message to this port then receive queue error status
+ * will turn as overrun and ignore the incoming message.
+ * If send message queue is full and client request to send message then he
+ * will wait for time provided by the parameter.
+ * @param MaxMessageSize Specifies the maximum size of the message in bytes
+ * which client can receive and transmit through this port.
+ *
+ * @retval NvSuccess New queue depth is set
+ * @retval NvError_NotInitialized hTransport is not open.
+ * @retval NvError_BadValue The parameter passed is not correct. There is
+ * limitation for maximum message q and message length from the driver and if
+ * this parameter is larger than those value then it returns this error.
+ *
+ */
+
+ NvError NvRmTransportSetQueueDepth(
+ NvRmTransportHandle hTransport,
+ NvU32 MaxQueueDepth,
+ NvU32 MaxMessageSize );
+
+/**
+ * Sends a message to the other port which is connected to this port.
+ * This will use the copy method to copy the client buffer message to
+ * transport message buffer. This function queue the message to the transmit
+ * queue. the data will be send later based on the physical transfer channel
+ * availablity.
+ *
+ * @see NvRmTransportOpen()
+ * @see NvRmTransportSetQueueDepth()
+ * @see NvRmTransportRecvMsg()
+ *
+ * @param hTransport Specifies the transport connection
+ * @param pMessageBuffer The pointer to the message buffer where message which
+ * need to be send is available.
+ * @param MessageSize Specifies the size of the message.
+ * @param TimeoutMS Specifies the amount of time (in milliseconds) to wait for
+ * sent message to be queued for the transfer. If the transmit queue if full
+ * then this function will block the client till maximum of timeout to queue
+ * this message. If meesage queue is available before timeout then it will
+ * queue the message and comeout. If message queue is full and timeout happen
+ * the it will return the timeout error.
+ * if zero timeout is selecetd and the message queue is full then it will be
+ * return NvError_TransportMessageBoxFull error.
+ * Avalue of NV_WAIT_INFINITE means "wait indefinitely" for queueing the
+ * message.
+ *
+ * @retval NvSuccess Message is queued successfully.
+ * @retval NvError_NotInitialized hTransport is not open.
+ * @retval NvError_BadValue The parameter passed is not valid.
+ * @retval NvError_InvalidState The port is not connected to the other port and
+ * it is not ready for sending the message.
+ * @retval NvError_Timeout Timed out waiting for message to be queue if send
+ * message queue.
+ * @retval NvError_TransportMessageBoxFull Message box is full and it is not
+ * able to queue the message.
+ */
+
+ NvError NvRmTransportSendMsg(
+ NvRmTransportHandle hTransport,
+ void* pMessageBuffer,
+ NvU32 MessageSize,
+ NvU32 TimeoutMS );
+
+/**
+ * Sends a message to the other port which is connected to this port.
+ * This function is to be used ONLY when we're about to enter LP0!
+ * There is no synchronization in this function as only one person
+ * should be talking to the AVP at the time of LP0. The message is sent
+ * on the RPC_AVP_PORT. In the future, there might be instances where
+ * we need to talk on a different port in LP0.
+ *
+ * @retval NvSuccess Message is queued successfully.
+ * @retval NvError_TransportMessageBoxFull Message box is full and it is not
+ * able to queue the message.
+ */
+
+ NvError NvRmTransportSendMsgInLP0(
+ NvRmTransportHandle hPort,
+ void* message,
+ NvU32 MessageSize );
+
+/**
+ * Receive the message from the port. This will read the message if it is
+ * available for this port otherwise it will return the
+ * NvError_TransportMessageBoxEmpty error.
+ *
+ * @see NvRmTransportOpen()
+ * @see NvRmTransportSetQueueDepth()
+ * @see NvRmTransportSendMsg()
+ *
+ * @param hTransport Specifies the transport connection
+ * @param pMessageBuffer The pointer to the receive message buffer where the
+ * received message will be copied.
+ * @param MaxSize The maximum size in bytes that may be copied to the buffer
+ * @param pMessageSize Pointer to the variable where the length of the message
+ * will be stored.
+ *
+ * @retval NvSuccess Message received successfully.
+ * @retval NvError_NotInitialized hTransport is not open.
+ * @retval NvError_InvalidState The port is not connection state.
+ * @retval NvError_TransportMessageBoxEmpty The message box empty and not able
+ * to receive the message.
+ * @retval NvError_TransportIncompleteMessage The received message for this
+ * port is longer than the configured message length for this port. It copied
+ * the maximm size of the configured length of the message for this port and
+ * return the incomplete message buffer.
+ * @retval NvError_TransportMessageOverflow The port receives the message more
+ * than the configured queue depth count for this port and hence message
+ * overflow has been ocuured.
+ */
+
+ NvError NvRmTransportRecvMsg(
+ NvRmTransportHandle hTransport,
+ void* pMessageBuffer,
+ NvU32 MaxSize,
+ NvU32 * pMessageSize );
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/include/nvrm_xpc.h b/arch/arm/mach-tegra/include/nvrm_xpc.h
new file mode 100644
index 000000000000..69b61d8d1147
--- /dev/null
+++ b/arch/arm/mach-tegra/include/nvrm_xpc.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_nvrm_xpc_H
+#define INCLUDED_nvrm_xpc_H
+
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+#include "nvrm_module.h"
+#include "nvrm_init.h"
+
+#include "nvcommon.h"
+#include "nvos.h"
+#include "nvrm_init.h"
+#include "nvrm_interrupt.h"
+
+/**
+ * @brief 16 Byte allignment for the shared memory message transfer.
+ */
+
+typedef enum
+{
+ XPC_MESSAGE_ALIGNMENT_SIZE = 0x10,
+ Xpc_Alignment_Num,
+ Xpc_Alignment_Force32 = 0x7FFFFFFF
+} Xpc_Alignment;
+
+/**
+ * NvRmPrivXpcMessageHandle is an opaque handle to NvRmPrivXpcMessage.
+ *
+ * @ingroup nvrm_xpc
+ */
+
+typedef struct NvRmPrivXpcMessageRec *NvRmPrivXpcMessageHandle;
+
+/**
+ * Create the xpc message handles for sending/receiving the message to/from
+ * target processor.
+ * This function allocates the memory (from multiprocessor shared memory
+ * region) and os resources for the message transfer and synchrnoisation.
+ *
+ * @see NvRmPrivXpcSendMessage()
+ * @see NvRmPrivXpcGetMessage()
+ *
+ * @param hDevice Handle to the Rm device which is required by Ddk to acquire
+ * the resources from RM.
+ * @param phXpcMessage Pointer to the handle to Xpc message where created
+ * Xpc message handle is stored.
+ *
+ * @retval NvSuccess Indicates the message queue is successfully created.
+ * @retval NvError_BadValue The parameter passed are incorrect.
+ * @retval NvError_InsufficientMemory Indicates that function fails to allocate the
+ * memory for message queue.
+ * @retval NvError_MemoryMapFailed Indicates that the memory mapping for xpc
+ * controller register failed.
+ * @retval NvError_NotSupported Indicates that the requested operation is not
+ * supported for the given target processor/Instance.
+ *
+ */
+
+ NvError NvRmPrivXpcCreate(
+ NvRmDeviceHandle hDevice,
+ NvRmPrivXpcMessageHandle * phXpcMessage );
+
+/**
+ * Destroy the created Xpc message handle. This frees all the resources
+ * allocated for the xpc message handle.
+ *
+ * @note After calling this function client will not able to send/receive any
+ * message.
+ *
+ * @see NvRmPrivXpcMessageCreate()
+ *
+ * @param hXpcMessage Xpc message queue handle which need to be destroy.
+ * This cas created when function NvRmPrivXpcMessageCreate() was called.
+ *
+ */
+
+ void NvRmPrivXpcDestroy(
+ NvRmPrivXpcMessageHandle hXpcMessage );
+
+ NvError NvRmPrivXpcSendMessage(
+ NvRmPrivXpcMessageHandle hXpcMessage,
+ NvU32 data );
+
+ NvU32 NvRmPrivXpcGetMessage(
+ NvRmPrivXpcMessageHandle hXpcMessage );
+
+/**
+ * Initializes the Arbitration semaphore system for cross processor synchronization.
+ *
+ * @param hDevice The RM handle.
+ *
+ * @retval "NvError_IrqRegistrationFailed" if interupt is already registred.
+ * @retval "NvSuccess" if successfull.
+ */
+
+ NvError NvRmXpcInitArbSemaSystem(
+ NvRmDeviceHandle hDevice );
+
+/**
+ * Tries to obtain a hw arbitration semaphore. This API is used to
+ * synchronize access to hw blocks across processors.
+ *
+ * @param modId The module that we need to cross-processor safe access to.
+ */
+
+ void NvRmXpcModuleAcquire(
+ NvRmModuleID modId );
+
+/**
+ * Releases the arbitration semaphore corresponding to the given module id.
+ *
+ * @param modId The module that we are releasing.
+ */
+
+ void NvRmXpcModuleRelease(
+ NvRmModuleID modId );
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/Makefile b/arch/arm/mach-tegra/nvrm/core/ap15/Makefile
index 34a7465bd6f9..85675a55c0fa 100644
--- a/arch/arm/mach-tegra/nvrm/core/ap15/Makefile
+++ b/arch/arm/mach-tegra/nvrm/core/ap15/Makefile
@@ -32,3 +32,5 @@ obj-y += ap16rm_reloctable.o
obj-y += ap15rm_init.o
obj-y += ap15rm_init_common.o
obj-y += ap15rm_interrupt.o
+obj-y += ap15rm_xpc.o
+obj-y += ap15rm_xpc_hw_private.o
diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_init.c b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_init.c
index c5f849c6da98..9392cdab7679 100644
--- a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_init.c
+++ b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_init.c
@@ -42,6 +42,7 @@
#include "nvrm_heap.h"
#include "nvrm_pmu_private.h"
#include "nvrm_processor.h"
+#include "nvrm_xpc.h"
#include "ap15rm_private.h"
#include "nvrm_structure.h"
#include "ap15rm_private.h"
@@ -428,6 +429,11 @@ NvRmOpenNew(NvRmDeviceHandle *pHandle)
}
}
}
+ err = NvRmXpcInitArbSemaSystem(rm);
+ if( err != NvSuccess )
+ {
+ goto fail;
+ }
/* assign the handle pointer */
*pHandle = rm;
@@ -730,3 +736,4 @@ void NvRmPrivMcErrorMonitorStop( NvRmDeviceHandle rm )
}
}
+
diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_xpc.c b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_xpc.c
new file mode 100644
index 000000000000..8b92ae4b5933
--- /dev/null
+++ b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_xpc.c
@@ -0,0 +1,432 @@
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * @brief <b>nVIDIA Driver Development Kit:
+ * Cross Proc Communication driver </b>
+ *
+ * @b Description: Implements the interface to the NvDdk XPC.
+ *
+ */
+
+#include "nvrm_xpc.h"
+#include "nvrm_memmgr.h"
+#include "ap15rm_xpc_hw_private.h"
+#include "nvrm_hardware_access.h"
+#include "nvassert.h"
+#include "ap15/ararb_sema.h"
+#include "ap15/arictlr_arbgnt.h"
+#include "nvrm_avp_shrd_interrupt.h"
+
+// Minimum sdram offset required so that avp can access the address which is
+// passed.
+// AVP can not access the 0x0000:0000 to 0x0000:0040
+enum { MIN_SDRAM_OFFSET = 0x100};
+
+
+//There are only 32 arb semaphores
+#define MAX_ARB_NUM 32
+
+#define ARBSEMA_REG_READ(pArbSemaVirtAdd, reg) \
+ NV_READ32(pArbSemaVirtAdd + (ARB_SEMA_##reg##_0))
+
+#define ARBSEMA_REG_WRITE(pArbSemaVirtAdd, reg, data) \
+ NV_WRITE32(pArbSemaVirtAdd + (ARB_SEMA_##reg##_0), (data));
+
+#define ARBGNT_REG_READ(pArbGntVirtAdd, reg) \
+ NV_READ32(pArbGntVirtAdd + (ARBGNT_##reg##_0))
+
+#define ARBGNT_REG_WRITE(pArbGntVirtAdd, reg, data) \
+ NV_WRITE32(pArbGntVirtAdd + (ARBGNT_##reg##_0), (data));
+
+static NvOsInterruptHandle s_arbInterruptHandle = NULL;
+
+// Combines the Processor Xpc system details. This contains the details of the
+// receive/send message queue and messaging system.
+typedef struct NvRmPrivXpcMessageRec
+{
+ NvRmDeviceHandle hDevice;
+
+ // Hw mail box register.
+ CpuAvpHwMailBoxReg HwMailBoxReg;
+
+} NvRmPrivXpcMessage;
+
+typedef struct NvRmPrivXpcArbSemaRec
+{
+ NvRmDeviceHandle hDevice;
+ NvU8 *pArbSemaVirtAddr;
+ NvU8 *pArbGntVirtAddr;
+ NvOsSemaphoreHandle semaphore[MAX_ARB_NUM];
+ NvOsMutexHandle mutex[MAX_ARB_NUM];
+ NvOsIntrMutexHandle hIntrMutex;
+
+} NvRmPrivXpcArbSema;
+
+static NvRmPrivXpcArbSema s_ArbSema;
+
+//Forward declarations
+static NvError InitArbSemaSystem(NvRmDeviceHandle hDevice);
+static void ArbSemaIsr(void *args);
+NvU32 GetArbIdFromRmModuleId(NvRmModuleID modId);
+/**
+ * Initialize the cpu avp hw mail box address and map the hw register address
+ * to virtual address.
+ * Thread Safety: Caller responsibility
+ */
+static NvError
+InitializeCpuAvpHwMailBoxRegister(NvRmPrivXpcMessageHandle hXpcMessage)
+{
+ NvError e;
+ NvRmPhysAddr ResourceSemaPhysAddr;
+
+ // Get base address of the hw mail box register. This register is in the set
+ // of resource semaphore module Id.
+ NvRmModuleGetBaseAddress(hXpcMessage->hDevice,
+ NVRM_MODULE_ID(NvRmModuleID_ResourceSema, 0),
+ &ResourceSemaPhysAddr, &hXpcMessage->HwMailBoxReg.BankSize);
+
+ // Map the base address to the virtual address.
+ hXpcMessage->HwMailBoxReg.pHwMailBoxRegBaseVirtAddr = NULL;
+ NV_CHECK_ERROR(NvRmPhysicalMemMap(
+ ResourceSemaPhysAddr, hXpcMessage->HwMailBoxReg.BankSize,
+ NVOS_MEM_READ_WRITE, NvOsMemAttribute_Uncached,
+ (void **)&hXpcMessage->HwMailBoxReg.pHwMailBoxRegBaseVirtAddr));
+
+ NvRmPrivXpcHwResetOutbox(&hXpcMessage->HwMailBoxReg);
+
+ return NvSuccess;
+}
+
+/**
+ * DeInitialize the cpu avp hw mail box address and unmap the hw register address
+ * virtual address.
+ * Thread Safety: Caller responsibility
+ */
+static void DeInitializeCpuAvpHwMailBoxRegister(NvRmPrivXpcMessageHandle hXpcMessage)
+{
+ // Unmap the hw register base virtual address
+ NvRmPhysicalMemUnmap(hXpcMessage->HwMailBoxReg.pHwMailBoxRegBaseVirtAddr,
+ hXpcMessage->HwMailBoxReg.BankSize);
+ hXpcMessage->HwMailBoxReg.pHwMailBoxRegBaseVirtAddr = NULL;
+}
+
+/**
+ * Create the cpu-avp messaging system.
+ * This function will call other helper function to create the messaging technique
+ * used for cpu-avp communication.
+ * Thread Safety: Caller responsibility
+ */
+static NvError
+CreateCpuAvpMessagingSystem(NvRmPrivXpcMessageHandle hXpcMessage)
+{
+ NvError Error = NvSuccess;
+
+ Error = InitializeCpuAvpHwMailBoxRegister(hXpcMessage);
+
+#if NV_IS_AVP
+ hXpcMessage->HwMailBoxReg.IsCpu = NV_FALSE;
+#else
+ hXpcMessage->HwMailBoxReg.IsCpu = NV_TRUE;
+#endif
+
+ // If error found then destroy all the allocation and initialization,
+ if (Error)
+ DeInitializeCpuAvpHwMailBoxRegister(hXpcMessage);
+
+ return Error;
+}
+
+
+/**
+ * Destroy the cpu-avp messaging system.
+ * This function destroy all the allocation/initialization done for creating
+ * the cpu-avp messaging system.
+ * Thread Safety: Caller responsibility
+ */
+static void DestroyCpuAvpMessagingSystem(NvRmPrivXpcMessageHandle hXpcMessage)
+{
+ // Destroy the cpu-avp hw mail box registers.
+ DeInitializeCpuAvpHwMailBoxRegister(hXpcMessage);
+ hXpcMessage->HwMailBoxReg.pHwMailBoxRegBaseVirtAddr = NULL;
+ hXpcMessage->HwMailBoxReg.BankSize = 0;
+}
+
+
+NvError
+NvRmPrivXpcCreate(
+ NvRmDeviceHandle hDevice,
+ NvRmPrivXpcMessageHandle *phXpcMessage)
+{
+ NvError Error = NvSuccess;
+ NvRmPrivXpcMessageHandle hNewXpcMsgHandle = NULL;
+
+ *phXpcMessage = NULL;
+
+ // Allocates the memory for the xpc message handle.
+ hNewXpcMsgHandle = NvOsAlloc(sizeof(*hNewXpcMsgHandle));
+ if (!hNewXpcMsgHandle)
+ {
+ return NvError_InsufficientMemory;
+ }
+
+ // Initialize all the members of the xpc message handle.
+ hNewXpcMsgHandle->hDevice = hDevice;
+ hNewXpcMsgHandle->HwMailBoxReg.pHwMailBoxRegBaseVirtAddr = NULL;
+ hNewXpcMsgHandle->HwMailBoxReg.BankSize = 0;
+
+ // Create the messaging system between the processors.
+ Error = CreateCpuAvpMessagingSystem(hNewXpcMsgHandle);
+
+ // if error the destroy all allocations done here.
+ if (Error)
+ {
+ NvOsFree(hNewXpcMsgHandle);
+ hNewXpcMsgHandle = NULL;
+ }
+
+#if NV_IS_AVP
+ Error = InitArbSemaSystem(hDevice);
+ if (Error)
+ {
+ NvOsFree(hNewXpcMsgHandle);
+ hNewXpcMsgHandle = NULL;
+ }
+#endif
+
+ // Copy the new xpc message handle into the passed parameter.
+ *phXpcMessage = hNewXpcMsgHandle;
+ return Error;
+}
+
+
+/**
+ * Destroy the Rm Xpc message handle.
+ * Thread Safety: It is provided inside the function.
+ */
+void NvRmPrivXpcDestroy(NvRmPrivXpcMessageHandle hXpcMessage)
+{
+ // If not a null pointer then destroy.
+ if (hXpcMessage)
+ {
+ // Destroy the messaging system between processor.
+ DestroyCpuAvpMessagingSystem(hXpcMessage);
+
+ // Free the allocated memory for the xpc message handle.
+ NvOsFree(hXpcMessage);
+ }
+}
+
+
+// Set the outbound mailbox with the given data. We might have to spin until
+// it's safe to send the message.
+NvError
+NvRmPrivXpcSendMessage(NvRmPrivXpcMessageHandle hXpcMessage, NvU32 data)
+{
+ NvRmPrivXpcHwSendMessageToTarget(&hXpcMessage->HwMailBoxReg, data);
+ return NvSuccess;
+}
+
+
+// Get the value currently in the inbox register. This read clears the incoming
+// interrupt.
+NvU32
+NvRmPrivXpcGetMessage(NvRmPrivXpcMessageHandle hXpcMessage)
+{
+ NvU32 data;
+ NvRmPrivXpcHwReceiveMessageFromTarget(&hXpcMessage->HwMailBoxReg, &data);
+ return data;
+}
+
+NvError NvRmXpcInitArbSemaSystem(NvRmDeviceHandle hDevice)
+{
+#if NV_IS_AVP
+ return NvSuccess;
+#else
+ return InitArbSemaSystem(hDevice);
+#endif
+}
+
+static NvError InitArbSemaSystem(NvRmDeviceHandle hDevice)
+{
+ NvOsInterruptHandler ArbSemaHandler;
+ NvRmPhysAddr ArbSemaBase, ArbGntBase;
+ NvU32 ArbSemaSize, ArbGntSize;
+ NvU32 irq;
+ NvError e;
+ NvU32 i = 0;
+
+ irq = NvRmGetIrqForLogicalInterrupt(
+ hDevice, NvRmModuleID_ArbitrationSema, 0);
+
+ ArbSemaHandler = ArbSemaIsr;
+
+ NV_CHECK_ERROR_CLEANUP(
+ NvRmInterruptRegister(hDevice, 1, &irq, &ArbSemaHandler,
+ hDevice, &s_arbInterruptHandle, NV_TRUE)
+ );
+
+ NvRmModuleGetBaseAddress(hDevice,
+ NVRM_MODULE_ID(NvRmModuleID_ArbitrationSema, 0),
+ &ArbSemaBase, &ArbSemaSize);
+
+ NvRmModuleGetBaseAddress(hDevice,
+ NVRM_MODULE_ID(NvRmPrivModuleID_InterruptArbGnt, 0),
+ &ArbGntBase, &ArbGntSize);
+
+ NV_CHECK_ERROR_CLEANUP(
+ NvRmPhysicalMemMap(ArbSemaBase, ArbSemaSize, NVOS_MEM_READ_WRITE,
+ NvOsMemAttribute_Uncached, (void**)&s_ArbSema.pArbSemaVirtAddr)
+ );
+
+ NV_CHECK_ERROR_CLEANUP(
+ NvRmPhysicalMemMap(ArbGntBase, ArbGntSize, NVOS_MEM_READ_WRITE,
+ NvOsMemAttribute_Uncached, (void**)&s_ArbSema.pArbGntVirtAddr)
+ );
+
+ //Initialize all the semaphores and mutexes
+ for (i=0;i<MAX_ARB_NUM;i++)
+ {
+ NV_CHECK_ERROR_CLEANUP(
+ NvOsSemaphoreCreate(&s_ArbSema.semaphore[i], 0)
+ );
+
+ NV_CHECK_ERROR_CLEANUP(
+ NvOsMutexCreate(&s_ArbSema.mutex[i])
+ );
+ }
+
+ NV_CHECK_ERROR_CLEANUP(
+ NvOsIntrMutexCreate(&s_ArbSema.hIntrMutex)
+ );
+
+fail:
+
+ return e;
+}
+
+
+static void ArbSemaIsr(void *args)
+{
+ NvU32 int_mask, proc_int_enable, arb_gnt, i = 0;
+
+ NvOsIntrMutexLock(s_ArbSema.hIntrMutex);
+ //Check which arb semaphores have been granted to this processor
+ arb_gnt = ARBSEMA_REG_READ(s_ArbSema.pArbSemaVirtAddr, SMP_GNT_ST);
+
+ //Figure out which arb semaphores were signalled and then disable them.
+#if NV_IS_AVP
+ proc_int_enable = ARBGNT_REG_READ(s_ArbSema.pArbGntVirtAddr, COP_ENABLE);
+ int_mask = arb_gnt & proc_int_enable;
+ ARBGNT_REG_WRITE(s_ArbSema.pArbGntVirtAddr,
+ COP_ENABLE, (proc_int_enable & ~int_mask));
+#else
+ proc_int_enable = ARBGNT_REG_READ(s_ArbSema.pArbGntVirtAddr, CPU_ENABLE);
+ int_mask = arb_gnt & proc_int_enable;
+ ARBGNT_REG_WRITE(s_ArbSema.pArbGntVirtAddr,
+ CPU_ENABLE, (proc_int_enable & ~int_mask));
+#endif
+
+ //Signal all the required semaphores
+ do
+ {
+ if (int_mask & 0x1)
+ {
+ NvOsSemaphoreSignal(s_ArbSema.semaphore[i]);
+ }
+ int_mask >>= 1;
+ i++;
+
+ } while (int_mask);
+
+ NvOsIntrMutexUnlock(s_ArbSema.hIntrMutex);
+ NvRmInterruptDone(s_arbInterruptHandle);
+}
+
+NvU32 GetArbIdFromRmModuleId(NvRmModuleID modId)
+{
+ NvU32 arbId;
+
+ switch(modId)
+ {
+ case NvRmModuleID_BseA:
+ arbId = NvRmArbSema_Bsea;
+ break;
+ case NvRmModuleID_Vde:
+ default:
+ arbId = NvRmArbSema_Vde;
+ break;
+ }
+
+ return arbId;
+}
+
+void NvRmXpcModuleAcquire(NvRmModuleID modId)
+{
+ NvU32 RequestedSemaNum;
+ NvU32 reg;
+
+ RequestedSemaNum = GetArbIdFromRmModuleId(modId);
+
+ NvOsMutexLock(s_ArbSema.mutex[RequestedSemaNum]);
+ NvOsIntrMutexLock(s_ArbSema.hIntrMutex);
+
+ //Try to grab the lock
+ ARBSEMA_REG_WRITE(s_ArbSema.pArbSemaVirtAddr, SMP_GET, 1 << RequestedSemaNum);
+
+ //Enable arb sema interrupt
+#if NV_IS_AVP
+ reg = ARBGNT_REG_READ(s_ArbSema.pArbGntVirtAddr, COP_ENABLE);
+ reg |= (1 << RequestedSemaNum);
+ ARBGNT_REG_WRITE(s_ArbSema.pArbGntVirtAddr, COP_ENABLE, reg);
+#else
+ reg = ARBGNT_REG_READ(s_ArbSema.pArbGntVirtAddr, CPU_ENABLE);
+ reg |= (1 << RequestedSemaNum);
+ ARBGNT_REG_WRITE(s_ArbSema.pArbGntVirtAddr, CPU_ENABLE, reg);
+#endif
+
+ NvOsIntrMutexUnlock(s_ArbSema.hIntrMutex);
+ NvOsSemaphoreWait(s_ArbSema.semaphore[RequestedSemaNum]);
+}
+
+void NvRmXpcModuleRelease(NvRmModuleID modId)
+{
+ NvU32 RequestedSemaNum;
+
+ RequestedSemaNum = GetArbIdFromRmModuleId(modId);
+
+ //Release the lock
+ ARBSEMA_REG_WRITE(s_ArbSema.pArbSemaVirtAddr, SMP_PUT, 1 << RequestedSemaNum);
+
+ NvOsMutexUnlock(s_ArbSema.mutex[RequestedSemaNum]);
+}
diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_xpc_hw_private.c b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_xpc_hw_private.c
new file mode 100644
index 000000000000..ffd1dc5d6ebd
--- /dev/null
+++ b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_xpc_hw_private.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * @brief <b>nVIDIA Driver Development Kit:
+ * Cross Processor Communication driver </b>
+ *
+ * @b Description: Implements the cross processor communication Hw Access APIs
+ *
+ */
+
+#include "nvcommon.h"
+#include "nvassert.h"
+#include "nvrm_drf.h"
+#include "nvrm_hardware_access.h"
+#include "ap15rm_xpc_hw_private.h"
+#include "ap15/arres_sema.h"
+
+enum {MESSAGE_BOX_MESSAGE_LENGTH_BITS = 28};
+#define RESSEMA_REG_READ32(pResSemaHwRegVirtBaseAdd, reg) \
+ NV_READ32((pResSemaHwRegVirtBaseAdd) + (RES_SEMA_##reg##_0)/4)
+
+#define RESSEMA_REG_WRITE32(pResSemaHwRegVirtBaseAdd, reg, val) \
+ do { \
+ NV_WRITE32(((pResSemaHwRegVirtBaseAdd) + ((RES_SEMA_##reg##_0)/4)), (val)); \
+ } while(0)
+
+void NvRmPrivXpcHwResetOutbox(CpuAvpHwMailBoxReg *pHwMailBoxReg)
+{
+ NvU32 OutboxMessage;
+ NvU32 OutboxVal;
+
+ OutboxMessage = 0;
+
+ // Write Outbox in the message box
+ // Enable the Valid tag
+ // Enable interrupt
+#if NV_IS_AVP
+ OutboxVal = RESSEMA_REG_READ32(pHwMailBoxReg->pHwMailBoxRegBaseVirtAddr,SHRD_INBOX);
+ OutboxVal = NV_FLD_SET_DRF_NUM(RES_SEMA, SHRD_INBOX, IN_BOX_STAT, 0, OutboxVal);
+ OutboxVal = NV_FLD_SET_DRF_NUM(RES_SEMA, SHRD_INBOX, IN_BOX_DATA, 0, OutboxVal);
+ OutboxVal = NV_FLD_SET_DRF_NUM(RES_SEMA, SHRD_INBOX, IN_BOX_CMD, 0, OutboxVal);
+ OutboxVal |= OutboxMessage;
+ OutboxVal = NV_FLD_SET_DRF_NUM(RES_SEMA, SHRD_INBOX, IE_IBE, 0, OutboxVal);
+ OutboxVal = NV_FLD_SET_DRF_NUM(RES_SEMA, SHRD_INBOX, TAG, 0, OutboxVal);
+ RESSEMA_REG_WRITE32(pHwMailBoxReg->pHwMailBoxRegBaseVirtAddr, SHRD_INBOX, OutboxVal);
+#else
+ OutboxVal = RESSEMA_REG_READ32(pHwMailBoxReg->pHwMailBoxRegBaseVirtAddr,SHRD_OUTBOX);
+ OutboxVal = NV_FLD_SET_DRF_NUM(RES_SEMA, SHRD_OUTBOX, OUT_BOX_CMD, 0, OutboxVal);
+ OutboxVal = NV_FLD_SET_DRF_NUM(RES_SEMA, SHRD_OUTBOX, OUT_BOX_STAT, 0, OutboxVal);
+ OutboxVal = NV_FLD_SET_DRF_NUM(RES_SEMA, SHRD_OUTBOX, OUT_BOX_DATA, 0, OutboxVal);
+ OutboxVal |= OutboxMessage;
+ OutboxVal = NV_FLD_SET_DRF_NUM(RES_SEMA, SHRD_OUTBOX, IE_OBE, 0, OutboxVal);
+ OutboxVal = NV_FLD_SET_DRF_NUM(RES_SEMA, SHRD_OUTBOX, TAG, 0, OutboxVal);
+ RESSEMA_REG_WRITE32(pHwMailBoxReg->pHwMailBoxRegBaseVirtAddr, SHRD_OUTBOX, OutboxVal);
+#endif
+}
+
+
+/**
+ * Send message to the target.
+ */
+void
+NvRmPrivXpcHwSendMessageToTarget(
+ CpuAvpHwMailBoxReg *pHwMailBoxReg,
+ NvRmPhysAddr MessageAddress)
+{
+ NvU32 OutboxMessage;
+ NvU32 OutboxVal = 0;
+
+ OutboxMessage = ((NvU32)(MessageAddress)) >> (32 - MESSAGE_BOX_MESSAGE_LENGTH_BITS);
+
+ // Write Outbox in the message box
+ // Enable the Valid tag
+ // Enable interrupt
+#if NV_IS_AVP
+ // !!! not sure why this would need to be read/modify/write
+// OutboxVal = RESSEMA_REG_READ32(pHwMailBoxReg->pHwMailBoxRegBaseVirtAddr,SHRD_INBOX);
+ OutboxVal = NV_FLD_SET_DRF_NUM(RES_SEMA, SHRD_INBOX, IN_BOX_STAT, 0, OutboxVal);
+ OutboxVal = NV_FLD_SET_DRF_NUM(RES_SEMA, SHRD_INBOX, IN_BOX_DATA, 0, OutboxVal);
+ OutboxVal = NV_FLD_SET_DRF_NUM(RES_SEMA, SHRD_INBOX, IN_BOX_CMD, 0, OutboxVal);
+ OutboxVal |= OutboxMessage;
+ OutboxVal = NV_FLD_SET_DRF_DEF(RES_SEMA, SHRD_INBOX, IE_IBF, FULL, OutboxVal);
+// OutboxVal = NV_FLD_SET_DRF_DEF(RES_SEMA, SHRD_INBOX, IE_IBE, EMPTY, OutboxVal);
+ OutboxVal = NV_FLD_SET_DRF_DEF(RES_SEMA, SHRD_INBOX, TAG, VALID, OutboxVal);
+ RESSEMA_REG_WRITE32(pHwMailBoxReg->pHwMailBoxRegBaseVirtAddr, SHRD_INBOX, OutboxVal);
+#else
+ // !!! not sure why this would need to be read/modify/write
+// OutboxVal = RESSEMA_REG_READ32(pHwMailBoxReg->pHwMailBoxRegBaseVirtAddr,SHRD_OUTBOX);
+ OutboxVal = NV_FLD_SET_DRF_NUM(RES_SEMA, SHRD_OUTBOX, OUT_BOX_CMD, 0, OutboxVal);
+ OutboxVal = NV_FLD_SET_DRF_NUM(RES_SEMA, SHRD_OUTBOX, OUT_BOX_STAT, 0, OutboxVal);
+ OutboxVal = NV_FLD_SET_DRF_NUM(RES_SEMA, SHRD_OUTBOX, OUT_BOX_DATA, 0, OutboxVal);
+ OutboxVal |= OutboxMessage;
+ OutboxVal = NV_FLD_SET_DRF_DEF(RES_SEMA, SHRD_OUTBOX, IE_OBF, FULL, OutboxVal);
+// OutboxVal = NV_FLD_SET_DRF_DEF(RES_SEMA, SHRD_OUTBOX, IE_OBE, EMPTY, OutboxVal);
+ OutboxVal = NV_FLD_SET_DRF_DEF(RES_SEMA, SHRD_OUTBOX, TAG, VALID, OutboxVal);
+ RESSEMA_REG_WRITE32(pHwMailBoxReg->pHwMailBoxRegBaseVirtAddr, SHRD_OUTBOX, OutboxVal);
+#endif
+}
+
+
+
+/**
+ * Receive message from the target.
+ */
+void
+NvRmPrivXpcHwReceiveMessageFromTarget(
+ CpuAvpHwMailBoxReg *pHwMailBoxReg,
+ NvRmPhysAddr *pMessageAddress)
+{
+ NvU32 InboxMessage = 0;
+ NvU32 InboxVal;
+
+ // Read the inbox. Lower 28 bit contains the message.
+#if NV_IS_AVP
+ InboxVal = RESSEMA_REG_READ32(pHwMailBoxReg->pHwMailBoxRegBaseVirtAddr,SHRD_OUTBOX);
+ RESSEMA_REG_WRITE32(pHwMailBoxReg->pHwMailBoxRegBaseVirtAddr, SHRD_OUTBOX, 0);
+#else
+ InboxVal = RESSEMA_REG_READ32(pHwMailBoxReg->pHwMailBoxRegBaseVirtAddr,SHRD_INBOX);
+ RESSEMA_REG_WRITE32(pHwMailBoxReg->pHwMailBoxRegBaseVirtAddr, SHRD_INBOX, 0);
+#endif
+ if (InboxVal & NV_DRF_DEF(RES_SEMA, SHRD_INBOX, TAG, VALID))
+ {
+ pHwMailBoxReg->MailBoxData = InboxVal;
+ }
+
+ InboxVal = (pHwMailBoxReg->MailBoxData) & (0xFFFFFFFFUL >> (32 - MESSAGE_BOX_MESSAGE_LENGTH_BITS));
+ InboxMessage = (InboxVal << (32 - MESSAGE_BOX_MESSAGE_LENGTH_BITS));
+
+ *pMessageAddress = InboxMessage;
+}
+
+
+
+
diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_xpc_hw_private.h b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_xpc_hw_private.h
new file mode 100644
index 000000000000..c5822526b9c8
--- /dev/null
+++ b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_xpc_hw_private.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * @brief <b>nVIDIA Driver Development Kit:
+ * Priate Hw access function for XPC driver </b>
+ *
+ * @b Description: Defines the private interface functions for the xpc
+ *
+ */
+
+#ifndef INCLUDED_RM_XPC_HW_PRIVATE_H
+#define INCLUDED_RM_XPC_HW_PRIVATE_H
+
+
+#include "nvcommon.h"
+#include "nvrm_init.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+// Combines the cpu avp hw mail baox system information.
+typedef struct CpuAvpHwMailBoxRegRec
+{
+ // Hw mail box register virtual base address.
+ NvU32 *pHwMailBoxRegBaseVirtAddr;
+
+ // Bank size of the hw regsiter.
+ NvU32 BankSize;
+
+ // Tells whether this is on cpu or on Avp
+ NvBool IsCpu;
+
+ // Mail box data which was read last time.
+ NvU32 MailBoxData;
+} CpuAvpHwMailBoxReg;
+
+void NvRmPrivXpcHwResetOutbox(CpuAvpHwMailBoxReg *pHwMailBoxReg);
+
+/**
+ * Send message to the target.
+ */
+void
+NvRmPrivXpcHwSendMessageToTarget(
+ CpuAvpHwMailBoxReg *pHwMailBoxReg,
+ NvRmPhysAddr MessageAddress);
+
+/**
+ * Receive message from the target.
+ */
+void
+NvRmPrivXpcHwReceiveMessageFromTarget(
+ CpuAvpHwMailBoxReg *pHwMailBoxReg,
+ NvRmPhysAddr *pMessageAddress);
+
+
+#if defined(__cplusplus)
+ }
+#endif
+
+#endif // INCLUDED_RM_XPC_HW_PRIVATE_H
diff --git a/arch/arm/mach-tegra/nvrm/core/common/Makefile b/arch/arm/mach-tegra/nvrm/core/common/Makefile
index fcce9a5c566f..55c7f3042dbd 100644
--- a/arch/arm/mach-tegra/nvrm/core/common/Makefile
+++ b/arch/arm/mach-tegra/nvrm/core/common/Makefile
@@ -28,3 +28,4 @@ obj-y += nvrm_power.o
obj-y += nvrm_power_dfs.o
obj-y += nvrm_rmctrace.o
obj-y += nvrm_relocation_table.o
+obj-y += nvrm_transport.o
diff --git a/arch/arm/mach-tegra/nvrm/core/common/nvrm_message.h b/arch/arm/mach-tegra/nvrm/core/common/nvrm_message.h
new file mode 100644
index 000000000000..e32033f6aa05
--- /dev/null
+++ b/arch/arm/mach-tegra/nvrm/core/common/nvrm_message.h
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_NVRM_MESSAGE_H
+#define INCLUDED_NVRM_MESSAGE_H
+
+#include "nvrm_memmgr.h"
+#include "nvrm_module.h"
+#include "nvrm_transport.h"
+#include "nvrm_power.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+// Maximum message queue depth
+enum {MAX_QUEUE_DEPTH = 5};
+// Maximum message length
+enum {MAX_MESSAGE_LENGTH = 256};
+// Maximum argument size
+enum {MAX_ARGS_SIZE = 220};
+// Max String length
+enum {MAX_STRING_LENGTH = 200};
+
+typedef struct NvRmRPCRec
+{
+ NvRmTransportHandle svcTransportHandle;
+ NvOsSemaphoreHandle TransportRecvSemId;
+ NvOsMutexHandle RecvLock;
+ NvRmDeviceHandle hRmDevice;
+ NvBool isConnected;
+} NvRmRPC;
+
+typedef struct NvRmRPCRec *NvRmRPCHandle;
+
+void NvRmPrivProcessMessage(NvRmRPCHandle hRPCHandle, char *pRecvMessage, int messageLength);
+
+typedef enum
+{
+ NvRmMsg_MemHandleCreate = 0x0,
+ NvRmMsg_MemHandleCreate_Response,
+ NvRmMsg_MemHandleOpen,
+ NvRmMsg_MemHandleFree,
+ NvRmMsg_MemAlloc,
+ NvRmMsg_MemAlloc_Response,
+ NvRmMsg_MemPin,
+ NvRmMsg_MemPin_Response,
+ NvRmMsg_MemUnpin,
+ NvRmMsg_MemUnpin_Response,
+ NvRmMsg_MemGetAddress,
+ NvRmMsg_MemGetAddress_Response,
+ NvRmMsg_HandleFromId,
+ NvRmMsg_HandleFromId_Response,
+ NvRmMsg_PowerModuleClockControl,
+ NvRmMsg_PowerModuleClockControl_Response,
+ NvRmMsg_ModuleReset,
+ NvRmMsg_ModuleReset_Response,
+ NvRmMsg_PowerRegister,
+ NvRmMsg_PowerUnRegister,
+ NvRmMsg_PowerStarvationHint,
+ NvRmMsg_PowerBusyHint,
+ NvRmMsg_PowerBusyMultiHint,
+ NvRmMsg_PowerDfsGetState,
+ NvRmMsg_PowerDfsGetState_Response,
+ NvRmMsg_PowerResponse,
+ NvRmMsg_PowerModuleGetMaxFreq,
+ NvRmMsg_InitiateLP0,
+ NvRmMsg_InitiateLP0_Response,
+ NvRmMsg_RemotePrintf,
+ NvRmMsg_AttachModule,
+ NvRmMsg_AttachModule_Response,
+ NvRmMsg_DetachModule,
+ NvRmMsg_DetachModule_Response,
+ NvRmMsg_AVP_Reset,
+ NvRmMsg_Force32 = 0x7FFFFFFF
+}NvRmMsg;
+
+typedef struct{
+ NvRmMsg msg;
+ NvU32 size;
+}NvRmMessage_HandleCreat;
+
+typedef struct{
+ NvRmMsg msg;
+ NvRmMemHandle hMem;
+ NvError error;
+}NvRmMessage_HandleCreatResponse;
+
+typedef struct{
+ NvRmMsg msg;
+ NvRmMemHandle hMem;
+}NvRmMessage_HandleFree;
+
+typedef struct{
+ NvRmMsg msg;
+ NvError error;
+}NvRmMessage_Response;
+
+typedef struct{
+ NvRmMsg msg;
+ NvRmMemHandle hMem;
+ NvRmHeap Heaps[NvRmHeap_Num];
+ NvU32 NumHeaps;
+ NvU32 Alignment;
+ NvOsMemAttribute Coherency;
+}NvRmMessage_MemAlloc;
+
+typedef struct{
+ NvRmMsg msg;
+ NvRmMemHandle hMem;
+ NvU32 Offset;
+}NvRmMessage_GetAddress;
+
+typedef struct{
+ NvRmMsg msg;
+ NvU32 address;
+}NvRmMessage_GetAddressResponse;
+
+typedef struct{
+ NvRmMsg msg;
+ NvU32 id;
+}NvRmMessage_HandleFromId;
+
+typedef struct{
+ NvRmMsg msg;
+ NvRmMemHandle hMem;
+}NvRmMessage_Pin;
+
+typedef struct{
+ NvRmMsg msg;
+ NvU32 address;
+}NvRmMessage_PinResponse;
+
+typedef struct{
+ NvRmMsg msg;
+ NvRmModuleID ModuleId;
+ NvU32 ClientId;
+ NvBool Enable;
+}NvRmMessage_Module;
+
+typedef struct{
+ NvRmMsg msg;
+ NvU32 clientId;
+ NvOsSemaphoreHandle eventSema;
+}NvRmMessage_PowerRegister;
+
+typedef struct{
+ NvRmMsg msg;
+ NvU32 clientId;
+}NvRmMessage_PowerUnRegister;
+
+typedef struct{
+ NvRmMsg msg;
+ NvRmDfsClockId clockId;
+ NvU32 clientId;
+ NvBool starving;
+}NvRmMessage_PowerStarvationHint;
+
+typedef struct{
+ NvRmMsg msg;
+ NvRmDfsClockId clockId;
+ NvU32 clientId;
+ NvU32 boostDurationMS;
+ NvRmFreqKHz boostKHz;
+}NvRmMessage_PowerBusyHint;
+
+typedef struct{
+ NvRmMsg msg;
+ NvU32 numHints;
+ NvU8 busyHints[MAX_STRING_LENGTH];
+}NvRmMessage_PowerBusyMultiHint;
+
+typedef struct{
+ NvRmMsg msg;
+}NvRmMessage_PowerDfsGetState;
+
+typedef struct{
+ NvRmMsg msg;
+ NvError error;
+ NvU32 clientId;
+}NvRmMessage_PowerRegister_Response;
+
+typedef struct{
+ NvRmMsg msg;
+ NvRmDfsRunState state;
+}NvRmMessage_PowerDfsGetState_Response;
+
+typedef struct{
+ NvRmMsg msg;
+ NvRmModuleID moduleID;
+}NvRmMessage_PowerModuleGetMaxFreq;
+
+typedef struct{
+ NvRmMsg msg;
+ NvRmFreqKHz freqKHz;
+}NvRmMessage_PowerModuleGetMaxFreq_Response;
+
+typedef struct{
+ NvRmMsg msg;
+ NvU32 sourceAddr;
+ NvU32 bufferAddr;
+ NvU32 bufferSize;
+} NvRmMessage_InitiateLP0;
+
+typedef struct{
+ NvRmMsg msg;
+ const char string[MAX_STRING_LENGTH];
+} NvRmMessage_RemotePrintf;
+
+
+typedef struct{
+ NvRmMsg msg;
+ NvU32 entryAddress;
+ NvU32 size;
+ char args[MAX_ARGS_SIZE];
+ NvU32 reason;
+}NvRmMessage_AttachModule;
+
+typedef struct{
+ NvRmMsg msg;
+ NvError error;
+}NvRmMessage_AttachModuleResponse;
+
+typedef struct{
+ NvRmMsg msg;
+ NvU32 reason;
+ NvU32 entryAddress;
+}NvRmMessage_DetachModule;
+
+typedef struct{
+ NvRmMsg msg;
+ NvError error;
+}NvRmMessage_DetachModuleResponse;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif
diff --git a/arch/arm/mach-tegra/nvrm/core/common/nvrm_rpc.h b/arch/arm/mach-tegra/nvrm/core/common/nvrm_rpc.h
new file mode 100644
index 000000000000..d74ab4e30776
--- /dev/null
+++ b/arch/arm/mach-tegra/nvrm/core/common/nvrm_rpc.h
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NVRM_RPC_H
+#define NVRM_RPC_H
+
+/*
+ * nvrm_cpu_avp_rpc_private.h defines the private implementation functions to facilitate
+ * communication between processors (cpu and avp).
+ */
+
+#include "nvcommon.h"
+#include "nvos.h"
+#include "nvrm_init.h"
+#include "nvrm_message.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+/**
+ * Initialize RPC
+ *
+ * Init the RPC. Both the service and client
+ * to the service must call this API before calling to create each endpoint of the connection
+ * via NvRmPrivRPCConnect
+ *
+ * If PortName is too long or does not exist debug mode
+ * assert is encountered.
+ *
+ * @param hDeviceHandle rm device handle
+ * @param rpcPortName the port name
+ * @param hRPCHandle the RPC transport handle
+ *
+ * @retval NvError_SemaphoreCreateFailed Creaion of semaphore failed.
+ */
+ NvError NvRmPrivRPCInit( NvRmDeviceHandle hDeviceHandle, char* rpcPortName, NvRmRPCHandle *hRPCHandle );
+/**
+ * De-intialize the RPC and other resources.
+ * @param hRPCHandle the RPC transport handle
+ *
+ */
+void NvRmPrivRPCDeInit( NvRmRPCHandle hRPCHandle );
+
+/**
+ * Connect to RPC port
+ *
+ * Creates one end of a RPC connection. Both the service and client
+ * to the service must call this API to create each endpoint of the connection
+ * through a specified port
+ *
+ * If PortName is too long or does not exist debug mode
+ * assert is encountered.
+ *
+ * @param hRPCHandle the RPC transport handle
+ *
+ * @retval NvSuccess Transport endpoint successfully allocated
+ * @retval NvError_InsufficientMemory Not enough memory to allocate endpoint
+ * @retval NvError_MutexCreateFailed Creaion of mutex failed.
+ * @retval NvError_SemaphoreCreateFailed Creaion of semaphore failed.
+ * @retval NvError_SharedMemAllocFailed Creaion of shared memory allocation
+ * failed.
+ * @retval NvError_NotInitialized The transport is not able to initialzed the
+ * threads.
+ */
+ NvError NvRmPrivRPCConnect( NvRmRPCHandle hRPCHandle );
+
+ /**
+ * Connect to RPC port
+ *
+ * Creates one end of a RPC connection. Both the service and client
+ * to the service must call this API to create each endpoint of the connection
+ * through a specified port
+ *
+ * If PortName is too long or does not exist debug mode
+ * assert is encountered.
+ *
+ * @param hRPCHandle the RPC transport handle
+ *
+ * @retval NvSuccess Transport endpoint successfully allocated
+ * @retval NvError_InsufficientMemory Not enough memory to allocate endpoint
+ * @retval NvError_MutexCreateFailed Creaion of mutex failed.
+ * @retval NvError_SemaphoreCreateFailed Creaion of semaphore failed.
+ * @retval NvError_SharedMemAllocFailed Creaion of shared memory allocation
+ * failed.
+ * @retval NvError_NotInitialized The transport is not able to initialzed the
+ * threads.
+ */
+ NvError NvRmPrivRPCWaitForConnect( NvRmRPCHandle hRPCHandle );
+ /**
+ * Receive the message from the port. This will read the message if it is
+ * available for this port otherwise it will return the
+ * NvError_TransportMessageBoxEmpty error.
+ *
+ * @param hRPCHandle the RPC transport handle
+ * @param pMessageBuffer The pointer to the receive message buffer where the
+ * received message will be copied.
+ * @param pMessageSize Pointer to the variable where the length of the message
+ * will be stored.
+ *
+ * @retval NvSuccess Message received successfully.
+ * @retval NvError_NotInitialized hTransport is not open.
+ * @retval NvError_InvalidState The port is not connection state.
+ * @retval NvError_TransportMessageBoxEmpty The message box empty and not able
+ * to receive the message.
+ * @retval NvError_TransportIncompleteMessage The received message for this
+ * port is longer than the configured message length for this port. It copied
+ * the maximm size of the configured length of the message for this port and
+ * return the incomplete message buffer.
+ * @retval NvError_TransportMessageOverflow The port receives the message more
+ * than the configured queue depth count for this port and hence message
+ * overflow has been ocuured.
+ */
+
+ NvError NvRmPrivRPCRecvMsg( NvRmRPCHandle hRPCHandle, void* pMessageBuffer, NvU32 * pMessageSize );
+
+ /**
+ * Send Message.
+ *
+ * Sends a message to the other port which is connected to this port.
+ * Its a wrapper to rm transport send message
+ *
+ * @param hRPCHandle the RPC transport handle
+ * @param pMessageBuffer The pointer to the message buffer where message which
+ * need to be send is available.
+ * @param MessageSize Specifies the size of the message.
+ *
+ */
+void
+NvRmPrivRPCSendMsg(NvRmRPCHandle hRPCHandle,
+ void* pMessageBuffer,
+ NvU32 MessageSize);
+
+/**
+ * Send and Recieve message.
+ *
+ * Send and Recieve a message between port.
+ * Its a wrapper to rm transport send message with response
+ *
+ * @param hRPCHandle the RPC transport handle
+ * @param pRecvMessageBuffer The pointer to the receive message buffer where the
+ * received message will be copied.
+ * @param MaxSize The maximum size in bytes that may be copied to the buffer
+ * @param pMessageSize Pointer to the variable where the length of the message
+ * will be stored.
+ * @param pSendMessageBuffer The pointer to the message buffer where message which
+ * need to be send is available.
+ * @param MessageSize Specifies the size of the message.
+ *
+ */
+void
+NvRmPrivRPCSendMsgWithResponse(NvRmRPCHandle hRPCHandle,
+ void* pRecvMessageBuffer,
+ NvU32 MaxSize,
+ NvU32 *pMessageSize,
+ void* pSendMessageBuffer,
+ NvU32 MessageSize);
+
+
+/**
+ * Closes a transport connection. Proper closure of this connection requires
+ * that both the client and service call this API. Therefore, it is expected
+ * that the client and service message one another to coordinate the close.
+ *
+ */
+void NvRmPrivRPCClose(NvRmRPCHandle hRPCHandle);
+
+NvError NvRmPrivInitService(NvRmDeviceHandle hDeviceHandle);
+
+void NvRmPrivServiceDeInit(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif
diff --git a/arch/arm/mach-tegra/nvrm/core/common/nvrm_transport.c b/arch/arm/mach-tegra/nvrm/core/common/nvrm_transport.c
new file mode 100644
index 000000000000..ffc4f83196fc
--- /dev/null
+++ b/arch/arm/mach-tegra/nvrm/core/common/nvrm_transport.c
@@ -0,0 +1,1655 @@
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/** @file
+ * @brief <b>NVIDIA Driver Development Kit:
+ * Transport API</b>
+ *
+ * @b Description: This is the implementation of Transport API, which
+ * implements a simple means to pass messages across a port name regardless of
+ * port exist in what processor (on same processor or other processor).
+ */
+
+#include "nvrm_transport.h"
+#include "nvrm_xpc.h"
+#include "nvrm_interrupt.h"
+#include "nvrm_rpc.h"
+#include "nvutil.h"
+#include "nvassert.h"
+#include "nvcommon.h"
+#include "avp.h"
+
+#define LOOPBACK_PROFILE 0
+
+// indices where to save data for the loopback test
+#define LOOP_CPU_SEND_INDEX 0
+#define LOOP_AVP_ISR_INDEX 1
+#define LOOP_AVP_RECV_INDEX 2
+#define LOOP_AVP_SEND_INDEX 3
+#define LOOP_CPU_ISR_INDEX 4
+#define LOOP_CPU_RECV_INDEX 5
+
+#define SEMAPHORE_BASED_MUTUAL_EXCLUSION 0
+
+enum {MAX_INT_FOR_TRANSPORT = 2};
+
+// Interrupt bit index in the interrupt controller relocation table.
+enum {CPU_TRANSPORT_INT_OBE = 1};
+enum {CPU_TRANSPORT_INT_IBF = 0};
+enum {AVP_TRANSPORT_INT_OBE = 0};
+enum {AVP_TRANSPORT_INT_IBF = 1};
+
+// Some constraints parameter to develop the transport APIs.
+
+// Maximum port name length
+enum {MAX_PORT_NAME_LENGTH = 16};
+
+// Maximum possible message length between the ports
+#define MAX_COMMAND_SIZE 16
+
+// Message header size MessageCommand + port Name + message Length (24 Bytes)
+enum {MESSAGE_HEADER_SIZE = 0x20};
+
+// Maximum receive message queue depth
+enum {MAX_MESSAGE_DEPTH = 30};
+
+// Maximum time to wait for the response when open the port.
+enum {MAX_OPEN_TIMEOUT_MS = 200};
+
+// Try to resend the message after this time.
+enum {MESSAGE_RETRY_AFTER_MS = 500 };
+
+// Connection message transfer and response wait timeout.
+enum {MAX_CONNECTION_TIMEOUT_MS = 500 };
+
+
+
+// Transport Commands which uses to do the handshaking and message transfer
+// between the processor. This commands are send to the remote processor
+// when any type if transaction happens.
+typedef enum
+{
+ TransportCmd_None = 0x0,
+
+ // The first transport command from the cpu->avp will inform the
+ // avp of size of the buffer.
+ TransportCmd_SetBufferInfo,
+
+ // Transport command for staring the connection process.
+ TransportCmd_Connect,
+
+ // Transport command for disconnecting the port and deleting the port entry.
+ TransportCmd_Disconnect,
+
+ // Transport command which used for normal message transfer to the port.
+ TransportCmd_Message,
+
+ // When a command requires a response, the value in the command field will
+ // be changed by the called processor here to indicate that the response is ready.
+ TransportCmd_Response,
+
+ TransportCmd_Force32 = 0x7FFFFFFF
+
+} TransportCmd;
+
+
+
+// Ports (endpoint) state.
+typedef enum
+{
+ // Port is opened only.
+ PortState_Open = 0x1,
+
+ // Port is waiting for connection.
+ PortState_Waiting,
+
+ // Port is connected.
+ PortState_Connected,
+
+ // Port has been disconnected from other side. You can pop out messages
+ // but you can't send anymore
+ PortState_Disconnected,
+
+ // Set to destroy when there is someone waiting for a connection, but
+ // and a different thread calls to kill close the port.
+ PortState_Destroy,
+
+ PortState_Force32 = 0x7FFFFFFF
+} PortState;
+
+
+
+// Message list which will be queued in the port receive message queue.
+typedef struct RmReceiveMessageRec
+{
+ // Length of message.
+ NvU32 MessageLength;
+
+ // Fixed size message buffer where the receiving message will be store.
+ NvU8 MessageBuffer[MAX_MESSAGE_LENGTH];
+} RmReceiveMessage;
+
+
+// Combines the information for keeping the received messages to the
+// corresponding ports.
+typedef struct MessageQueueRec
+{
+ // Receive message Q details to receive the message. We make the queue 1 extra bigger than the
+ // requested size, and then we can do lockless updates because only the Recv function modifies
+ // ReadIndex, and only the ISR modifies the WriteIndex
+ RmReceiveMessage *pReceiveMsg;
+
+ volatile NvU16 ReadIndex;
+ volatile NvU16 WriteIndex;
+
+ NvU16 QueueSize;
+
+} MessageQueue;
+
+
+
+// Combines all required information for the transport port.
+// The port information contains the state, recv message q, message depth and
+// message length.
+typedef struct NvRmTransportRec
+{
+ // Name of the port, 1 exra byte for NULL termination
+ char PortName[MAX_PORT_NAME_LENGTH+1];
+
+ // The state of port whether this is open or connected or waiting for
+ // connection.
+ PortState State;
+
+ // Receive message Box which contains the receive messages for this port.
+ MessageQueue RecvMessageQueue;
+
+ // Semaphore which is signal after getting the message for that port.
+ // This is the client passed semaphore.
+ NvOsSemaphoreHandle hOnPushMsgSem;
+
+ // Pointer to the partner port. If the connect is to a remote partner,
+ // then this pointer is NULL
+ NvRmTransportHandle hConnectedPort;
+
+ // If this is a remote connection, this holds the remote ports "name"
+ NvU32 RemotePort;
+
+ // save a copy of the rm handle.
+ NvRmDeviceHandle hRmDevice;
+
+ struct NvRmTransportRec *pNext;
+
+ // unlikely to be used members at the end
+
+ // to be signalled when someone waits for a connector.
+ NvOsSemaphoreHandle hOnConnectSem;
+
+#if LOOPBACK_PROFILE
+ NvBool bLoopTest;
+#endif
+
+} NvRmTransport;
+
+
+
+// Combines the common information for keeping the transport information and
+// sending and receiving the messages.
+typedef struct NvRmPrivPortsRec
+{
+ // Device handle.
+ NvRmDeviceHandle hDevice;
+
+ // List of port names of the open ports in the system.
+ NvRmTransport *pPortHead;
+
+ // Mutex for transport
+ NvOsMutexHandle mutex;
+
+ NvRmMemHandle hMessageMem;
+ void *pTransmitMem;
+ void *pReceiveMem;
+ NvU32 MessageMemPhysAddr;
+
+ NvRmPrivXpcMessageHandle hXpc;
+
+ // if a message comes in, but the receiver's queue is full,
+ // then we don't clear the inbound message to allow another message
+ // and set this flag. We use 2 variables here, so we don't need a lock.
+ volatile NvU8 ReceiveBackPressureOn;
+ NvU8 ReceiveBackPressureOff;
+
+#if LOOPBACK_PROFILE
+ volatile NvU32 *pTimer;
+#endif
+} NvRmPrivPorts;
+
+
+// !!! Fixme, this should be part of the rm handle.
+static NvRmPrivPorts s_TransportInfo;
+
+extern NvU32 NvRmAvpPrivGetUncachedAddress(NvU32 addr);
+
+#define MESSAGE_QUEUE_SIZE_IN_BYTES ( sizeof(RmReceiveMessage) * (MAX_MESSAGE_DEPTH+1) )
+static NvU32 s_RpcAvpQueue[ (MESSAGE_QUEUE_SIZE_IN_BYTES + 3) / 4 ];
+static NvU32 s_RpcCpuQueue[ (MESSAGE_QUEUE_SIZE_IN_BYTES + 3) / 4 ];
+static struct NvRmTransportRec s_RpcAvpPortStruct;
+static struct NvRmTransportRec s_RpcCpuPortStruct;
+
+static NvOsInterruptHandle s_TransportInterruptHandle = NULL;
+
+static NvRmTransportHandle
+FindPort(NvRmDeviceHandle hDevice, char *pPortName);
+
+static NvError
+NvRmPrivTransportSendMessage(NvRmDeviceHandle hDevice, NvU32 *message, NvU32 MessageLength);
+
+static void HandleAVPResetMessage(NvRmDeviceHandle hDevice);
+
+// expect caller to handle mutex
+static char *NvRmPrivTransportUniqueName(void)
+{
+ static char UniqueName[] = "aaaaaaaa+";
+ NvU32 len = 8;
+ NvU32 i;
+
+ // this will roll a new name until we hit zzzz:zzzz
+ // it's not unbounded, but it is a lot of names...
+ // Unique names end in a '+' which won't be allowed in supplied names, to avoid
+ // collision.
+ for (i=0; i < len; ++i)
+ {
+ ++UniqueName[i];
+ if (UniqueName[i] != 'z')
+ {
+ break;
+ }
+ UniqueName[i] = 'a';
+
+ }
+
+ return UniqueName;
+}
+
+
+/* Returns NV_TRUE if the message was inserted ok
+ * Returns NV_FALSE if message was not inserted because the queue is already full
+
+ */static NvBool
+InsertMessage(NvRmTransportHandle hPort, const NvU8 *message, const NvU32 MessageSize)
+{
+ NvU32 index;
+ NvU32 NextIndex;
+
+ index = (NvU32)hPort->RecvMessageQueue.WriteIndex;
+ NextIndex = index + 1;
+ if (NextIndex == hPort->RecvMessageQueue.QueueSize)
+ NextIndex = 0;
+
+ // check for full condition
+ if (NextIndex == hPort->RecvMessageQueue.ReadIndex)
+ return NV_FALSE;
+
+ // copy in the message
+ NvOsMemcpy(hPort->RecvMessageQueue.pReceiveMsg[index].MessageBuffer,
+ message,
+ MessageSize);
+ hPort->RecvMessageQueue.pReceiveMsg[index].MessageLength = MessageSize;
+
+ hPort->RecvMessageQueue.WriteIndex = (NvU16)NextIndex;
+ return NV_TRUE;
+}
+
+
+static void
+ExtractMessage(NvRmTransportHandle hPort, NvU8 *message, NvU32 *pMessageSize, NvU32 MaxSize)
+{
+ NvU32 NextIndex;
+ NvU32 index = (NvU32)hPort->RecvMessageQueue.ReadIndex;
+ NvU32 size = hPort->RecvMessageQueue.pReceiveMsg[index].MessageLength;
+
+ NextIndex = index + 1;
+ if (NextIndex == hPort->RecvMessageQueue.QueueSize)
+ NextIndex = 0;
+
+ NV_ASSERT(index != hPort->RecvMessageQueue.WriteIndex); // assert on empty condition
+ NV_ASSERT(size <= MaxSize);
+
+ *pMessageSize = size;
+
+ // only do the copy and update if there is sufficient room, otherwise
+ // the caller will propogate an error up.
+ if (size > MaxSize)
+ {
+ return;
+ }
+ NvOsMemcpy(message,
+ hPort->RecvMessageQueue.pReceiveMsg[index].MessageBuffer,
+ size);
+
+ hPort->RecvMessageQueue.ReadIndex = (NvU16)NextIndex;
+}
+
+
+
+static void *s_TmpIsrMsgBuffer;
+
+/**
+ * Connect message
+ * [ Transport Command ]
+ * [ Remote Handle ]
+ * [ Port Name ]
+ *
+ * Response:
+ * [ Remote Handle ] <- [ Local Handle ]
+ */
+
+static void
+HandleConnectMessage(NvRmDeviceHandle hDevice, volatile NvU32 *pMessage)
+{
+ char PortName[MAX_PORT_NAME_LENGTH+1];
+ NvU32 RemotePort;
+ NvRmTransportHandle hPort;
+
+ RemotePort = pMessage[1];
+ NvOsMemcpy(PortName, (void*)&pMessage[2], MAX_PORT_NAME_LENGTH);
+ PortName[MAX_PORT_NAME_LENGTH] = 0;
+
+ // See if there is a local port with that name
+ hPort = FindPort(hDevice, PortName);
+ if (hPort && hPort->State == PortState_Waiting)
+ {
+ NvOsAtomicCompareExchange32((NvS32 *)&hPort->State, PortState_Waiting, PortState_Connected);
+ if (hPort->State == PortState_Connected)
+ {
+ hPort->RemotePort = RemotePort;
+ NvOsSemaphoreSignal(hPort->hOnConnectSem);
+ pMessage[1] = (NvU32)hPort;
+ }
+ else
+ {
+ pMessage[1] = 0;
+ }
+ }
+ else
+ {
+ pMessage[1] = 0;
+ }
+ pMessage[0] = TransportCmd_Response;
+}
+
+
+
+/**
+ * Disconnect message
+ * [ Transport Command ]
+ * [ Local Handle ]
+ *
+ * Response:
+ * [ Local Handle ] <- 0
+ */
+static void
+HandleDisconnectMessage(NvRmDeviceHandle hDevice, volatile NvU32 *pMessage)
+{
+ NvRmTransportHandle hPort;
+ hPort = (NvRmTransportHandle)pMessage[1];
+
+ // !!! For sanity we should walk the list of open ports to make sure this is a valid port!
+ if (hPort && hPort->State == PortState_Connected)
+ {
+ hPort->State = PortState_Disconnected;
+ hPort->RemotePort = 0;
+ }
+ pMessage[1] = 0;
+ pMessage[0] = TransportCmd_None;
+}
+
+
+/**
+ * Disconnect message
+ * [ Transport Command ]
+ * [ Local Handle ]
+ * [ Message Length ]
+ * [ Message ]
+ *
+ * Response:
+ * [ Message Length ] <- NvSuccess
+ * [ Transport Command ] <- When we can accept a new message
+ */
+
+static void
+HandlePortMessage(NvRmDeviceHandle hDevice, volatile NvU32 *pMessage)
+{
+ NvRmTransportHandle hPort;
+ NvU32 MessageLength;
+ NvBool bSuccess;
+
+ hPort = (NvRmTransportHandle)pMessage[1];
+ MessageLength = pMessage[2];
+
+#if LOOPBACK_PROFILE
+ if (hPort && hPort->bLoopTest)
+ {
+# if NV_IS_AVP
+ pMessage[LOOP_AVP_ISR_INDEX + 3] = *s_TransportInfo.pTimer;
+# else
+ pMessage[LOOP_CPU_ISR_INDEX + 3] = *s_TransportInfo.pTimer;
+# endif
+ }
+#endif
+
+
+ // !!! For sanity we should walk the list of open ports to make sure this is a valid port!
+ // Queue the message even if in the open state as presumably this should only have happened if
+ // due to a race condition with the transport connected messages.
+ if (hPort && (hPort->State == PortState_Connected || hPort->State == PortState_Open))
+ {
+ bSuccess = InsertMessage(hPort, (NvU8*)&pMessage[3], MessageLength);
+ if (bSuccess)
+ {
+ if (hPort->hOnPushMsgSem)
+ NvOsSemaphoreSignal(hPort->hOnPushMsgSem);
+ pMessage[0] = TransportCmd_None;
+ }
+ else
+ {
+ ++s_TransportInfo.ReceiveBackPressureOn;
+ }
+ }
+}
+
+static void
+HandleAVPResetMessage(NvRmDeviceHandle hDevice)
+{
+ NvRmTransportHandle hPort;
+
+ hPort = FindPort(hDevice,(char*)"RPC_CPU_PORT");
+ if (hPort && (hPort->State == PortState_Connected || hPort->State == PortState_Open))
+ {
+ NvU32 message;
+ message = NvRmMsg_AVP_Reset;
+ InsertMessage(hPort, (NvU8*)&message, sizeof(NvU32));
+ if (hPort->hOnPushMsgSem)
+ NvOsSemaphoreSignal(hPort->hOnPushMsgSem);
+ else
+ NV_ASSERT(0);
+ }
+ else
+ NV_ASSERT(0);
+
+}
+
+
+/**
+ * Handle the Inbox full interrupt.
+ */
+static void
+InboxFullIsr(void *args)
+{
+ NvRmDeviceHandle hDevice = (NvRmDeviceHandle)args;
+ NvU32 MessageData;
+ NvU32 MessageCommand;
+ volatile NvU32 *pMessage;
+
+ MessageData = NvRmPrivXpcGetMessage(s_TransportInfo.hXpc);
+ if(MessageData == AVP_WDT_RESET)
+ {
+ HandleAVPResetMessage(hDevice);
+ NvRmInterruptDone(s_TransportInterruptHandle);
+ return;
+ }
+ // if we're on the AVP, the first message we get will configure the message info
+ if (s_TransportInfo.MessageMemPhysAddr == 0)
+ {
+#if NV_IS_AVP
+ MessageData = NvRmAvpPrivGetUncachedAddress(MessageData);
+#else
+ MessageData = MessageData;
+#endif
+ s_TransportInfo.MessageMemPhysAddr = MessageData;
+ s_TransportInfo.pReceiveMem = (void*)MessageData;
+ s_TransportInfo.pTransmitMem = (void *) (MessageData + MAX_MESSAGE_LENGTH + MAX_COMMAND_SIZE);
+ // ack the message and return.
+ *(NvU32*)s_TransportInfo.pReceiveMem = TransportCmd_None;
+ return;
+ }
+
+ // otherwise decode and dispatch the message.
+
+
+ if (s_TransportInfo.pReceiveMem == NULL)
+ {
+ /* QT/EMUTRANS takes this path. */
+ NvRmMemRead(s_TransportInfo.hMessageMem, MAX_MESSAGE_LENGTH + MAX_COMMAND_SIZE, s_TmpIsrMsgBuffer, MAX_MESSAGE_LENGTH);
+ pMessage = s_TmpIsrMsgBuffer;
+ NvRmMemWrite(s_TransportInfo.hMessageMem, MAX_MESSAGE_LENGTH + MAX_COMMAND_SIZE, s_TmpIsrMsgBuffer, 2*sizeof(NvU32));
+ }
+ else
+ {
+ pMessage = (NvU32*)s_TransportInfo.pReceiveMem;
+ }
+
+ MessageCommand = pMessage[0];
+
+ switch (MessageCommand)
+ {
+ case TransportCmd_Connect:
+ HandleConnectMessage(hDevice, pMessage);
+ break;
+
+ case TransportCmd_Disconnect:
+ HandleDisconnectMessage(hDevice, pMessage);
+ break;
+
+ case TransportCmd_Message:
+ HandlePortMessage(hDevice, pMessage);
+ break;
+
+ default:
+ NV_ASSERT(0);
+ }
+
+ NvRmInterruptDone(s_TransportInterruptHandle);
+}
+
+
+/**
+ * Handle the outbox empty interrupt.
+ */
+static void
+OutboxEmptyIsr(void *args)
+{
+ // !!! This is not currently used... ignore for now. Might be required if we find that we
+ // need to spin for long periods of time waiting for other end of the connection to consume
+ // messages.
+ //
+ NvRmInterruptDone(s_TransportInterruptHandle);
+}
+
+static void
+NvRmPrivProcIdGetProcessorInfo(
+ NvRmDeviceHandle hDevice,
+ NvRmModuleID *pProcModuleId)
+{
+#if NV_IS_AVP
+ *pProcModuleId = NvRmModuleID_Avp;
+#else
+ *pProcModuleId = NvRmModuleID_Cpu;
+#endif
+}
+
+/**
+ * Register for the transport interrupts.
+ */
+static NvError
+RegisterTransportInterrupt(NvRmDeviceHandle hDevice)
+{
+ NvOsInterruptHandler DmaIntHandlers[MAX_INT_FOR_TRANSPORT];
+ NvU32 IrqList[MAX_INT_FOR_TRANSPORT];
+ NvRmModuleID ProcModuleId;
+
+ if (s_TransportInterruptHandle)
+ {
+ return NvSuccess;
+ }
+ NvRmPrivProcIdGetProcessorInfo(hDevice, &ProcModuleId);
+
+ if (ProcModuleId == NvRmModuleID_Cpu)
+ {
+ IrqList[0] = NvRmGetIrqForLogicalInterrupt(
+ hDevice, NvRmModuleID_ResourceSema, CPU_TRANSPORT_INT_IBF);
+ IrqList[1] = NvRmGetIrqForLogicalInterrupt(
+ hDevice, NvRmModuleID_ResourceSema, CPU_TRANSPORT_INT_OBE);
+ }
+ else
+ {
+ IrqList[0] = NvRmGetIrqForLogicalInterrupt(
+ hDevice, NvRmModuleID_ResourceSema, AVP_TRANSPORT_INT_IBF);
+ IrqList[1] = NvRmGetIrqForLogicalInterrupt(
+ hDevice, NvRmModuleID_ResourceSema, AVP_TRANSPORT_INT_OBE);
+ }
+
+ /* There is no need for registering the OutboxEmptyIsr, so we only register
+ * one interrupt i.e. InboxFullIsr */
+ DmaIntHandlers[0] = InboxFullIsr;
+ DmaIntHandlers[1] = OutboxEmptyIsr;
+ return NvRmInterruptRegister(hDevice, 1, IrqList, DmaIntHandlers,
+ hDevice, &s_TransportInterruptHandle, NV_TRUE);
+}
+
+// allocate buffers to be used for sending/receiving messages.
+static void
+NvRmPrivTransportAllocBuffers(NvRmDeviceHandle hRmDevice)
+{
+#if !NV_IS_AVP
+ // These buffers are always allocated on the CPU side. We'll pass the address over the AVP
+ //
+
+ NvError Error = NvSuccess;
+ NvRmMemHandle hNewMemHandle = NULL;
+
+ // Create memory handle
+ Error = NvRmMemHandleCreate(hRmDevice, &hNewMemHandle, (MAX_MESSAGE_LENGTH + MAX_COMMAND_SIZE)*2);
+ if (Error)
+ goto fail;
+
+ // Allocates the memory from the Heap
+ Error = NvRmMemAlloc(hNewMemHandle, NULL, 0,
+ XPC_MESSAGE_ALIGNMENT_SIZE, NvOsMemAttribute_Uncached);
+ if (Error)
+ goto fail;
+
+ s_TransportInfo.MessageMemPhysAddr = NvRmMemPin(hNewMemHandle);
+
+ // If it is success to create the memory handle.
+ // We have to be able to get a mapping to this, because it is used at interrupt time!
+ s_TransportInfo.hMessageMem = hNewMemHandle;
+ Error = NvRmMemMap(hNewMemHandle, 0,
+ (MAX_MESSAGE_LENGTH + MAX_COMMAND_SIZE)*2,
+ NVOS_MEM_READ_WRITE,
+ &s_TransportInfo.pTransmitMem);
+ if (Error)
+ {
+ s_TransportInfo.pTransmitMem = NULL;
+ s_TransportInfo.pReceiveMem = NULL;
+ }
+ else
+ {
+ s_TransportInfo.pReceiveMem = (void *) (((NvUPtr)s_TransportInfo.pTransmitMem) +
+ MAX_MESSAGE_LENGTH + MAX_COMMAND_SIZE);
+ }
+
+ s_TransportInfo.hMessageMem = hNewMemHandle;
+ NvRmMemWr32(hNewMemHandle, 0, 0xdeadf00d); // set this non-zero to throttle messages to the avp till avp is ready.
+ NvRmMemWr32(hNewMemHandle, MAX_MESSAGE_LENGTH + MAX_COMMAND_SIZE, 0);
+
+ NvRmPrivXpcSendMessage(s_TransportInfo.hXpc, s_TransportInfo.MessageMemPhysAddr);
+ return;
+
+
+fail:
+ NvRmMemHandleFree(hNewMemHandle);
+ s_TransportInfo.hMessageMem = NULL;
+ return;
+#else
+ return;
+#endif
+}
+
+
+static void
+NvRmPrivTransportFreeBuffers(NvRmDeviceHandle hRmDevice)
+{
+#if !NV_IS_AVP
+ NvRmMemHandleFree(s_TransportInfo.hMessageMem);
+#endif
+}
+
+static volatile NvBool s_Transport_Inited = NV_FALSE;
+
+/**
+ * Initialize the transport structures, this is callled once
+ * at NvRmOpen time.
+ */
+NvError NvRmTransportInit(NvRmDeviceHandle hRmDevice)
+{
+ NvError err;
+
+ NvOsMemset(&s_TransportInfo, 0, sizeof(s_TransportInfo));
+ s_TransportInfo.hDevice = hRmDevice;
+
+ err = NvOsMutexCreate(&s_TransportInfo.mutex);
+ if (err)
+ goto fail;
+
+#if !NVOS_IS_WINDOWS || NVOS_IS_WINDOWS_CE
+ err = NvRmPrivXpcCreate(hRmDevice, &s_TransportInfo.hXpc);
+ if (err)
+ goto fail;
+
+ NvRmPrivTransportAllocBuffers(hRmDevice);
+#endif
+
+ if (1) // Used in EMUTRANS mode where the buffers cannot be mapped.
+ {
+ s_TmpIsrMsgBuffer = NvOsAlloc(MAX_MESSAGE_LENGTH);
+ if (!s_TmpIsrMsgBuffer)
+ goto fail;
+ }
+
+#if LOOPBACK_PROFILE
+ {
+ NvU32 TimerAddr;
+ NvU32 TimerSize;
+
+ NvRmModuleGetBaseAddress(hRmDevice, NvRmModuleID_TimerUs, &TimerAddr, &TimerSize);
+ // map the us counter
+ err = NvRmPhysicalMemMap(TimerAddr, TimerSize, NVOS_MEM_READ_WRITE,
+ NvOsMemAttribute_Uncached, (void*)&s_TransportInfo.pTimer);
+ if (err)
+ goto fail;
+ }
+
+#endif
+
+#if !NVOS_IS_WINDOWS || NVOS_IS_WINDOWS_CE
+ err = RegisterTransportInterrupt(hRmDevice);
+ if (err)
+ goto fail;
+#endif
+ s_Transport_Inited = NV_TRUE;
+ return NvSuccess;
+
+
+fail:
+#if !NVOS_IS_WINDOWS || NVOS_IS_WINDOWS_CE
+ NvRmPrivXpcDestroy(s_TransportInfo.hXpc);
+ NvRmPrivTransportFreeBuffers(hRmDevice);
+#endif
+ NvOsFree(s_TmpIsrMsgBuffer);
+ NvOsMutexDestroy(s_TransportInfo.mutex);
+ return err;
+}
+
+/**
+ * DeInitialize the transport structures.
+ */
+void NvRmTransportDeInit(NvRmDeviceHandle hRmDevice)
+{
+ // Unregister the interrupts.
+#if !NVOS_IS_WINDOWS || NVOS_IS_WINDOWS_CE
+ NvRmPrivXpcDestroy(s_TransportInfo.hXpc);
+ NvRmPrivTransportFreeBuffers(hRmDevice);
+ NvRmInterruptUnregister(hRmDevice, s_TransportInterruptHandle);
+ s_TransportInterruptHandle = NULL;
+#endif
+ NvOsFree(s_TmpIsrMsgBuffer);
+ NvOsMutexDestroy(s_TransportInfo.mutex);
+}
+
+
+static void
+InsertPort(NvRmDeviceHandle hDevice, NvRmTransportHandle hPort)
+{
+ hPort->pNext = s_TransportInfo.pPortHead;
+ s_TransportInfo.pPortHead = hPort;
+}
+
+
+static NvRmTransportHandle
+FindPort(NvRmDeviceHandle hDevice, char *pPortName)
+{
+ NvRmTransportHandle hPort = NULL;
+ NvRmTransportHandle hIter = NULL;
+
+ hIter = s_TransportInfo.pPortHead;
+ while (hIter)
+ {
+ if ( NvOsStrcmp(pPortName, hIter->PortName) == 0)
+ {
+ hPort = hIter;
+ break;
+ }
+ hIter = hIter->pNext;
+ }
+
+ return hPort;
+}
+
+
+// Remove the given hPort from the list of ports
+static void
+DeletePort(NvRmDeviceHandle hRmDevice, const NvRmTransportHandle hPort)
+{
+ // Pointer to the pointer alleviates all special cases in linked list walking.
+ // I wish I was clever enough to have figured this out myself.
+
+ NvRmTransportHandle *hIter;
+
+ hIter = &s_TransportInfo.pPortHead;
+ while (*hIter)
+ {
+ if ( *hIter == hPort )
+ {
+ *hIter = (*hIter)->pNext;
+ break;
+ }
+ hIter = &(*hIter)->pNext;
+ }
+}
+
+
+
+
+/**
+ * Open the port handle with a given port name. With the same name, only two
+ * port can be open.
+ * Thread Safety: It is done inside the function.
+ */
+
+NvError
+NvRmTransportOpen(
+ NvRmDeviceHandle hRmDevice,
+ char *pPortName,
+ NvOsSemaphoreHandle RecvMessageSemaphore,
+ NvRmTransportHandle *phTransport)
+{
+ NvU32 PortNameLen;
+ NvRmTransportHandle hPartner = NULL;
+ NvRmTransportHandle hPort = NULL;
+ NvError err = NvError_InsufficientMemory;
+ char TmpName[MAX_PORT_NAME_LENGTH+1];
+
+ while (!s_Transport_Inited) {
+ // This can happen, if this API is called before avp init.
+ NvOsSleepMS(500);
+ }
+ // Look and see if this port exists anywhere.
+ if (pPortName == NULL)
+ {
+ NvOsMutexLock(s_TransportInfo.mutex);
+
+ pPortName = NvRmPrivTransportUniqueName();
+ PortNameLen = NvOsStrlen(pPortName);
+ NvOsStrncpy(TmpName, pPortName, sizeof(TmpName) );
+ pPortName = TmpName;
+
+ NvOsMutexUnlock(s_TransportInfo.mutex);
+ }
+ else
+ {
+ PortNameLen = NvOsStrlen(pPortName);
+ NV_ASSERT(PortNameLen <= MAX_PORT_NAME_LENGTH);
+ }
+
+ NvOsMutexLock(s_TransportInfo.mutex);
+ hPartner = FindPort(hRmDevice, pPortName);
+
+ if (hPartner && hPartner->hConnectedPort != NULL)
+ {
+ NvOsMutexUnlock(s_TransportInfo.mutex);
+ return NvError_TransportPortAlreadyExist;
+ }
+
+ // check if this is one of the special RPC ports used by the rm
+ if ( NvOsStrcmp(pPortName, "RPC_AVP_PORT") == 0)
+ {
+ //If someone else wants to open this port
+ //just return the one already created.
+ if (hPartner)
+ {
+ hPort = hPartner;
+ goto success;
+ }
+ else
+ {
+ hPort = &s_RpcAvpPortStruct;
+ hPort->RecvMessageQueue.pReceiveMsg = (void *)&s_RpcAvpQueue[0];
+ }
+ }
+ else if (NvOsStrcmp(pPortName, "RPC_CPU_PORT") == 0)
+ {
+ hPort = &s_RpcCpuPortStruct;
+ hPort->RecvMessageQueue.pReceiveMsg = (void *)&s_RpcCpuQueue[0];
+ }
+ else
+ {
+ // Create a new TransportPort
+ hPort = NvOsAlloc( sizeof(*hPort) );
+ if (!hPort)
+ goto fail;
+
+ NvOsMemset(hPort, 0, sizeof(*hPort) );
+
+ // Allocate the receive queue
+ hPort->RecvMessageQueue.pReceiveMsg = NvOsAlloc( sizeof(RmReceiveMessage) * (MAX_MESSAGE_DEPTH+1));
+ if (!hPort->RecvMessageQueue.pReceiveMsg)
+ goto fail;
+ }
+
+ NvOsStrncpy(hPort->PortName, pPortName, PortNameLen);
+ hPort->State = PortState_Open;
+ hPort->hConnectedPort = hPartner;
+
+ if (RecvMessageSemaphore)
+ {
+ err = NvOsSemaphoreClone(RecvMessageSemaphore, &hPort->hOnPushMsgSem);
+ if (err)
+ goto fail;
+ }
+
+ hPort->RecvMessageQueue.QueueSize = MAX_MESSAGE_DEPTH+1;
+ hPort->hRmDevice = hRmDevice;
+
+ if (hPort->hConnectedPort != NULL)
+ {
+ hPort->hConnectedPort->hConnectedPort = hPort;
+ }
+ InsertPort(hRmDevice, hPort);
+
+
+ // !!! loopback info
+#if LOOPBACK_PROFILE
+ if (NvOsStrcmp(hPort->PortName, "LOOPTEST") == 0)
+ hPort->bLoopTest = 1;
+#endif
+
+success:
+ NvOsMutexUnlock(s_TransportInfo.mutex);
+ *phTransport = hPort;
+ return NvSuccess;
+
+fail:
+ if (hPort)
+ {
+ NvOsFree(hPort->RecvMessageQueue.pReceiveMsg);
+ NvOsSemaphoreDestroy(hPort->hOnPushMsgSem);
+ NvOsFree(hPort);
+ hPort = NULL;
+ }
+ NvOsMutexUnlock(s_TransportInfo.mutex);
+
+ return err;
+}
+
+
+/**
+ * Close the transport handle
+ * Thread Safety: It is done inside the function.
+ */
+void NvRmTransportClose(NvRmTransportHandle hPort)
+{
+ NvU32 RemoteMessage[4];
+
+ if (!hPort)
+ return;
+
+ // Look and see if this port exists anywhere.
+ NV_ASSERT(hPort);
+
+
+ NvOsMutexLock(s_TransportInfo.mutex);
+ DeletePort(hPort->hRmDevice, hPort); // unlink this port
+
+ // Check if there is already a port waiting to connect, and if there is
+ // switch the port state to _Destroy, and signal the waiters semaphore.
+ // The "State" member is not protected by the mutex because it can be
+ // updated by the ISR.
+ while (hPort->State == PortState_Waiting)
+ {
+ NvOsAtomicCompareExchange32((NvS32*)&hPort->State, PortState_Waiting, PortState_Destroy);
+ if (hPort->State == PortState_Destroy)
+ {
+ NvOsSemaphoreSignal(hPort->hOnConnectSem);
+
+ // in this case, we can't complete the destroy, the signalled thread will
+ // have to complete. We just return now
+ NvOsMutexUnlock(s_TransportInfo.mutex);
+ return;
+ }
+ }
+
+ if (hPort->hConnectedPort)
+ {
+ // unlink this port from the other side of the connection.
+ hPort->hConnectedPort->hConnectedPort = NULL;
+ }
+
+ if (hPort->RemotePort)
+ {
+ RemoteMessage[0] = TransportCmd_Disconnect;
+ RemoteMessage[1] = hPort->RemotePort;
+ NvRmPrivTransportSendMessage(hPort->hRmDevice, RemoteMessage, 2*sizeof(NvU32));
+ }
+
+ NvOsSemaphoreDestroy(hPort->hOnPushMsgSem);
+
+
+ if (hPort == &s_RpcAvpPortStruct ||
+ hPort == &s_RpcCpuPortStruct)
+ {
+ // don't free these..
+ NvOsMemset(hPort, 0, sizeof(*hPort));
+ }
+ else
+ {
+ NvOsFree(hPort->RecvMessageQueue.pReceiveMsg);
+ NvOsFree(hPort);
+ }
+
+ NvOsMutexUnlock(s_TransportInfo.mutex);
+}
+
+
+/**
+ * Wait for the connection to the other end.
+ * Thread Safety: It is done inside the function.
+ */
+NvError
+NvRmTransportWaitForConnect(
+ NvRmTransportHandle hPort,
+ NvU32 TimeoutMS)
+{
+ NvOsSemaphoreHandle hSem = NULL;
+ NvError err = NvSuccess;
+
+ NvOsMutexLock(s_TransportInfo.mutex);
+ if (hPort->State != PortState_Open)
+ {
+ NvOsMutexUnlock(s_TransportInfo.mutex);
+ err = NvError_TransportPortAlreadyExist;
+ goto exit_gracefully;
+ }
+
+ err = NvOsSemaphoreCreate(&hSem, 0);
+ if (err)
+ {
+ NvOsMutexUnlock(s_TransportInfo.mutex);
+ goto exit_gracefully;
+ }
+
+ hPort->hOnConnectSem = hSem;
+ hPort->State = PortState_Waiting;
+ NvOsMutexUnlock(s_TransportInfo.mutex);
+
+ err = NvOsSemaphoreWaitTimeout(hSem, TimeoutMS);
+ if (err)
+ {
+ // we have to be careful here, the ISR _might_ happen just after the semaphore
+ // times out.
+ NvOsAtomicCompareExchange32((NvS32 *)&hPort->State, PortState_Waiting, PortState_Open);
+ NV_ASSERT(hPort->State == PortState_Open || hPort->State == PortState_Connected);
+ if (hPort->State == PortState_Connected)
+ {
+ err = NvSuccess;
+ }
+ }
+
+ NvOsMutexLock(s_TransportInfo.mutex);
+ hPort->hOnConnectSem = NULL;
+ NvOsMutexUnlock(s_TransportInfo.mutex);
+
+ if (hPort->State == PortState_Destroy)
+ {
+ // finish the destroy process
+ NvRmTransportClose(hPort);
+ err = NvError_TransportConnectionFailed;
+ }
+
+exit_gracefully:
+ NvOsSemaphoreDestroy(hSem);
+ return err;
+}
+
+
+
+static NvError
+NvRmPrivTransportWaitResponse(NvRmDeviceHandle hDevice, NvU32 *response, NvU32 ResponseLength, NvU32 TimeoutMS)
+{
+ NvU32 CurrentTime;
+ NvU32 StartTime;
+ NvU32 Response;
+ NvBool GotResponse = NV_TRUE;
+ NvError err = NvError_Timeout;
+ volatile NvU32 *pXpcMessage = (volatile NvU32*)s_TransportInfo.pTransmitMem;
+
+ if (pXpcMessage == NULL)
+ {
+ if (!NV_IS_AVP)
+ {
+ Response = NvRmMemRd32(s_TransportInfo.hMessageMem, 0);
+ } else
+ {
+ NV_ASSERT(0);
+ return NvSuccess;
+ }
+ }
+ else
+ {
+ Response = pXpcMessage[0];
+ }
+
+ if (Response != TransportCmd_Response)
+ {
+ GotResponse = NV_FALSE;
+
+ // response is not back yet, so spin till its here.
+ StartTime = NvOsGetTimeMS();
+ CurrentTime = StartTime;
+ while ( (CurrentTime - StartTime) < TimeoutMS )
+ {
+ if ( pXpcMessage && (pXpcMessage[0] == TransportCmd_Response) )
+ {
+ GotResponse = NV_TRUE;
+ break;
+ }
+ else if ( !pXpcMessage )
+ {
+ NV_ASSERT(!"Invalid pXpcMessage pointer is accessed");
+ }
+ CurrentTime = NvOsGetTimeMS();
+ }
+ }
+
+ if ( pXpcMessage && GotResponse )
+ {
+ err = NvSuccess;
+ NvOsMemcpy(response, (void *)pXpcMessage, ResponseLength);
+ }
+
+ return err;
+}
+
+
+static NvError
+NvRmPrivTransportSendMessage(NvRmDeviceHandle hDevice, NvU32 *message, NvU32 MessageLength)
+{
+ NvU32 ReadData;
+
+ if (s_TransportInfo.pTransmitMem == NULL)
+ {
+ /* QT/EMUTRANS takes this code path */
+ if (!NV_IS_AVP)
+ {
+ ReadData = NvRmMemRd32(s_TransportInfo.hMessageMem, 0);
+ } else
+ {
+ NV_ASSERT(0);
+ return NvSuccess;
+ }
+ }
+ else
+ {
+ ReadData = ((NvU32*)s_TransportInfo.pTransmitMem)[0];
+ }
+
+ // Check for clear to send
+ if ( ReadData != 0)
+ return NvError_TransportMessageBoxFull; // someone else is sending a message
+
+ if (s_TransportInfo.pTransmitMem == NULL)
+ {
+ /* QT/EMUTRANS takes this code path */
+ NvRmMemWrite(s_TransportInfo.hMessageMem, 0, message, MessageLength);
+ }
+ else
+ {
+ NvOsMemcpy(s_TransportInfo.pTransmitMem, message, MessageLength);
+ NvOsFlushWriteCombineBuffer();
+ }
+ NvRmPrivXpcSendMessage(s_TransportInfo.hXpc, s_TransportInfo.MessageMemPhysAddr);
+ return NvSuccess;
+}
+
+NvError
+NvRmTransportSendMsgInLP0(NvRmTransportHandle hPort, void *pMessageBuffer, NvU32 MessageSize)
+{
+ NvU32 ReadData;
+ NvU32 Message[3 + ((MAX_MESSAGE_LENGTH) / sizeof(NvU32))];
+
+ NV_ASSERT(pMessageBuffer);
+
+ Message[0] = TransportCmd_Message;
+ Message[1] = hPort->RemotePort;
+ Message[2] = MessageSize;
+
+ if (MessageSize)
+ NvOsMemcpy(&Message[3], pMessageBuffer, MessageSize);
+
+ ReadData = ((NvU32*)s_TransportInfo.pTransmitMem)[0];
+
+ // Check for clear to send
+ if ( ReadData != 0)
+ return NvError_TransportMessageBoxFull; // someone else is sending a message
+
+ NvOsMemcpy(s_TransportInfo.pTransmitMem, Message, MessageSize + 3*sizeof(NvU32));
+ NvOsFlushWriteCombineBuffer();
+
+ NvRmPrivXpcSendMessage(s_TransportInfo.hXpc, s_TransportInfo.MessageMemPhysAddr);
+ return NvSuccess;
+}
+
+static void
+NvRmPrivTransportClearSend(NvRmDeviceHandle hDevice)
+{
+ if (s_TransportInfo.pTransmitMem == NULL)
+ {
+ /* QT/EMUTRANS take this path */
+ if (!NV_IS_AVP)
+ {
+ NvRmMemWr32(s_TransportInfo.hMessageMem, 0, TransportCmd_None);
+ } else
+ {
+ NV_ASSERT(0);
+ }
+ }
+ else
+ {
+ ((NvU32*)s_TransportInfo.pTransmitMem)[0] = TransportCmd_None;
+ }
+}
+
+/**
+ * Make the connection to the other end.
+ * Thread Safety: It is done inside the function.
+ */
+NvError NvRmTransportConnect(NvRmTransportHandle hPort, NvU32 TimeoutMS)
+{
+ NvRmTransportHandle hPartnerPort;
+ NvU32 StartTime;
+ NvU32 CurrentTime;
+ NvU32 ConnectMessage[ MAX_PORT_NAME_LENGTH/4 + 3];
+ NvError err;
+
+
+ // Look and see if there is a local port with the same name that is currently waiting, if there is
+ // mark both ports as connected.
+
+ NV_ASSERT(hPort);
+ NV_ASSERT(hPort->hRmDevice);
+ NV_ASSERT(hPort->State == PortState_Open);
+
+
+ StartTime = NvOsGetTimeMS();
+ for (;;)
+ {
+ // Someone is waiting for a connection here locally.
+ NvOsMutexLock(s_TransportInfo.mutex);
+
+ hPartnerPort = hPort->hConnectedPort;
+ if (hPartnerPort)
+ {
+ // Found a local connection
+ if (hPartnerPort->State == PortState_Waiting)
+ {
+
+ hPartnerPort->State = PortState_Connected;
+ hPartnerPort->hConnectedPort = hPort;
+
+ hPort->State = PortState_Connected;
+ NvOsSemaphoreSignal(hPartnerPort->hOnConnectSem);
+ break;
+ }
+ }
+ else if (s_TransportInfo.hMessageMem || s_TransportInfo.pReceiveMem) // if no shared buffer, then we can't create a remote connection.
+ {
+ ConnectMessage[0] = TransportCmd_Connect;
+ ConnectMessage[1] = (NvU32)hPort;
+ NvOsMemcpy(&ConnectMessage[2], hPort->PortName, MAX_PORT_NAME_LENGTH);
+
+ err = NvRmPrivTransportSendMessage(hPort->hRmDevice, ConnectMessage, sizeof(ConnectMessage));
+ if (!err)
+ {
+ // should send back 2 words of data. Give remote side 1000ms to respond, which should be about 100x more
+ // than it needs.
+ NvU32 WaitTime = NV_MAX(1000, TimeoutMS);
+ if (TimeoutMS == NV_WAIT_INFINITE)
+ TimeoutMS = NV_WAIT_INFINITE;
+
+ // !!! Note, we can do this without holding the mutex...
+ err = NvRmPrivTransportWaitResponse(hPort->hRmDevice, ConnectMessage, 2*sizeof(NvU32), WaitTime);
+ NvRmPrivTransportClearSend(hPort->hRmDevice);
+ if (err)
+ {
+ // the other side is not responding to messages, doh!
+ NvOsMutexUnlock(s_TransportInfo.mutex);
+ return NvError_TransportConnectionFailed;
+ }
+
+ // check the response
+ hPort->RemotePort = ConnectMessage[1];
+ if (hPort->RemotePort != 0)
+ {
+ hPort->State = PortState_Connected;
+ break;
+ }
+ }
+ }
+ NvOsMutexUnlock(s_TransportInfo.mutex);
+ NV_ASSERT(hPort->State == PortState_Open); // it better still be open
+
+ // Didn't find a connection, wait a few ms and then try again
+ CurrentTime = NvOsGetTimeMS();
+ if ( (CurrentTime - StartTime) > TimeoutMS )
+ return NvError_Timeout;
+
+ NvOsSleepMS(10);
+ }
+
+ NvOsMutexUnlock(s_TransportInfo.mutex);
+ return NvSuccess;
+}
+
+
+/**
+ * Set the queue depth and message size of the transport handle.
+ * Thread Safety: It is done inside the function.
+ */
+NvError NvRmTransportSetQueueDepth(
+ NvRmTransportHandle hPort,
+ NvU32 MaxQueueDepth,
+ NvU32 MaxMessageSize)
+{
+ RmReceiveMessage *pNewReceiveMsg = NULL;
+
+ NV_ASSERT(hPort != NULL);
+ NV_ASSERT(MaxQueueDepth != 0);
+ NV_ASSERT(MaxMessageSize != 0);
+
+ // You cannot change the queue after a connection has been opened
+ NV_ASSERT(hPort->State == PortState_Open);
+
+ // !!! FIXME
+ // Xpc does not allow changing the base message size, so we can't change the message size here (yet!)
+ // Once we have per port message buffers we can set this.
+ NV_ASSERT(MaxMessageSize <= MAX_MESSAGE_LENGTH);
+
+ // These are statically allocated ports, they cannot be modified!
+ // !!! FIXME: this is just a sanity check. Remove this and make it so that
+ // cpu/avp rpc doesn't call this function and just knows that the
+ // transport will give it a port with a large enough queue to support
+ // rpc, since rpc ports and queue are statically allocated this has to be true.
+ if (hPort == &s_RpcAvpPortStruct ||
+ hPort == &s_RpcCpuPortStruct)
+ {
+ if (MaxMessageSize <= MAX_MESSAGE_LENGTH &&
+ MaxQueueDepth <= MAX_MESSAGE_DEPTH)
+ {
+ return NvSuccess;
+ }
+
+ NV_ASSERT(!" Illegal meesage length or queue depth. ");
+ }
+
+ // Freeing default allocated message queue.
+ NvOsFree(hPort->RecvMessageQueue.pReceiveMsg);
+ hPort->RecvMessageQueue.pReceiveMsg = NULL;
+ // create a new message queue struct, one longer than requested on purpose.
+ pNewReceiveMsg = NvOsAlloc( sizeof(RmReceiveMessage) * (MaxQueueDepth+1));
+ if (pNewReceiveMsg == NULL)
+ return NvError_InsufficientMemory;
+
+ hPort->RecvMessageQueue.pReceiveMsg = pNewReceiveMsg;
+ hPort->RecvMessageQueue.QueueSize = (NvU16)(MaxQueueDepth+1);
+
+ return NvSuccess;
+}
+
+
+static NvError
+NvRmPrivTransportSendRemoteMsg(
+ NvRmTransportHandle hPort,
+ void* pMessageBuffer,
+ NvU32 MessageSize,
+ NvU32 TimeoutMS)
+{
+ NvError err;
+ NvU32 StartTime;
+ NvU32 CurrentTime;
+ NvU32 Message[3 + ((MAX_MESSAGE_LENGTH) / sizeof(NvU32))];
+
+ NV_ASSERT((MAX_MESSAGE_LENGTH) >= MessageSize);
+
+ StartTime = NvOsGetTimeMS();
+
+ Message[0] = TransportCmd_Message;
+ Message[1] = hPort->RemotePort;
+ Message[2] = MessageSize;
+
+ NvOsMemcpy(&Message[3], pMessageBuffer, MessageSize);
+
+ for (;;)
+ {
+ NvOsMutexLock(s_TransportInfo.mutex);
+ err = NvRmPrivTransportSendMessage(hPort->hRmDevice, Message, MessageSize + 3*sizeof(NvU32));
+ NvOsMutexUnlock(s_TransportInfo.mutex);
+ if (err == NvSuccess)
+ {
+ return NvSuccess;
+ }
+
+ // Sleep and then try again in a few ms to send again
+ CurrentTime = NvOsGetTimeMS();
+ if ( TimeoutMS != NV_WAIT_INFINITE && (CurrentTime - StartTime) > TimeoutMS )
+ return NvError_Timeout;
+
+ NvOsSleepMS(1); // try again later...
+ }
+}
+
+
+
+static NvError
+NvRmPrivTransportSendLocalMsg(
+ NvRmTransportHandle hPort,
+ void* pMessageBuffer,
+ NvU32 MessageSize,
+ NvU32 TimeoutMS)
+{
+ NvU32 CurrentTime;
+ NvU32 StartTime;
+ NvError err = NvSuccess;
+
+ NvRmTransportHandle hRemotePort;
+
+ NvOsMutexLock(s_TransportInfo.mutex);
+ hRemotePort = hPort->hConnectedPort;
+
+
+ StartTime = NvOsGetTimeMS();
+
+ for (;;)
+ {
+ // try to insert into the message into the receivers queue.
+ NvBool bSuccess = InsertMessage(hRemotePort, (NvU8*)pMessageBuffer, MessageSize);
+ if (bSuccess)
+ {
+ if (hRemotePort->hOnPushMsgSem)
+ NvOsSemaphoreSignal(hRemotePort->hOnPushMsgSem);
+ break;
+ }
+
+ // The destination port is full.
+ if (TimeoutMS == 0)
+ {
+ err = NvError_TransportMessageBoxFull;
+ break;
+ }
+
+ // The user wants a timeout, so we just sleep a short time so the
+ // other thread can pop a message. It would be better to use another semaphore
+ // to indicate that the box is not full, but that just seems overkill since this
+ // should rarely happen anyhow.
+ // unlock the mutex, and wait a small amount of time.
+ NvOsMutexUnlock(s_TransportInfo.mutex);
+
+ NvOsSleepMS(1);
+ NvOsMutexLock(s_TransportInfo.mutex);
+ if (TimeoutMS != NV_WAIT_INFINITE)
+ {
+ // check for a timeout condition.
+ CurrentTime = NvOsGetTimeMS();
+ if ( (CurrentTime - StartTime) >= TimeoutMS)
+ {
+ err = NvError_Timeout;
+ break;
+ }
+ }
+ }
+ NvOsMutexUnlock(s_TransportInfo.mutex);
+
+ return err;
+}
+
+
+/**
+ * Send the message to the other end port.
+ * Thread Safety: It is done inside the function.
+ */
+NvError
+NvRmTransportSendMsg(
+ NvRmTransportHandle hPort,
+ void* pMessageBuffer,
+ NvU32 MessageSize,
+ NvU32 TimeoutMS)
+{
+ NvError err;
+
+ NV_ASSERT(hPort);
+ NV_ASSERT(hPort->State == PortState_Connected);
+ NV_ASSERT(pMessageBuffer);
+
+#if LOOPBACK_PROFILE
+ if (hPort->bLoopTest)
+ {
+# if NV_IS_AVP
+ ((NvU32*)pMessageBuffer)[LOOP_AVP_SEND_INDEX] = *s_TransportInfo.pTimer;
+# else
+ ((NvU32*)pMessageBuffer)[LOOP_CPU_SEND_INDEX] = *s_TransportInfo.pTimer;
+# endif
+ }
+#endif
+
+ if (hPort->hConnectedPort)
+ {
+ err = NvRmPrivTransportSendLocalMsg(hPort, pMessageBuffer, MessageSize, TimeoutMS);
+ }
+ else if (hPort->State == PortState_Connected)
+ {
+ err = NvRmPrivTransportSendRemoteMsg(hPort, pMessageBuffer, MessageSize, TimeoutMS);
+ }
+ else
+ {
+ NV_ASSERT(0); // someone did something naughty
+ err = NvError_TransportNotConnected;
+ }
+
+ return err;
+}
+
+
+
+/**
+ * Receive the message from the other end port.
+ * Thread Safety: It is done inside the function.
+ */
+NvError
+NvRmTransportRecvMsg(
+ NvRmTransportHandle hPort,
+ void* pMessageBuffer,
+ NvU32 MaxSize,
+ NvU32 *pMessageSize)
+{
+ NvU8 TmpMessage[MAX_MESSAGE_LENGTH];
+
+ NV_ASSERT(hPort);
+ NV_ASSERT( (hPort->State == PortState_Connected) || (hPort->State == PortState_Disconnected) );
+ NV_ASSERT(pMessageBuffer);
+ NV_ASSERT(pMessageSize);
+
+
+ NvOsMutexLock(s_TransportInfo.mutex);
+ if (hPort->RecvMessageQueue.ReadIndex == hPort->RecvMessageQueue.WriteIndex)
+ {
+ NvOsMutexUnlock(s_TransportInfo.mutex);
+ return NvError_TransportMessageBoxEmpty;
+ }
+
+ ExtractMessage(hPort, (NvU8*)pMessageBuffer, pMessageSize, MaxSize);
+ if (*pMessageSize > MaxSize)
+ {
+ // not enough room to copy the message
+ NvOsMutexUnlock(s_TransportInfo.mutex);
+ NV_ASSERT(!" RM Transport: Illegal message size. ");
+ }
+
+
+ // if there was backpressure asserted, try to handle the currently posted message, and re-enable messages
+ if (s_TransportInfo.ReceiveBackPressureOn != s_TransportInfo.ReceiveBackPressureOff)
+ {
+ NV_ASSERT( ((NvU8)s_TransportInfo.ReceiveBackPressureOn) == ((NvU8)(s_TransportInfo.ReceiveBackPressureOff+1)) );
+ ++s_TransportInfo.ReceiveBackPressureOff;
+
+ if (s_TransportInfo.pReceiveMem == NULL)
+ {
+ /* QT/EMUTRANS takes this path. */
+ NvRmMemRead(s_TransportInfo.hMessageMem,
+ MAX_MESSAGE_LENGTH + MAX_COMMAND_SIZE,
+ TmpMessage,
+ MAX_MESSAGE_LENGTH);
+ HandlePortMessage(hPort->hRmDevice, (volatile void *)TmpMessage);
+ NvRmMemWrite(s_TransportInfo.hMessageMem,
+ MAX_MESSAGE_LENGTH + MAX_COMMAND_SIZE,
+ TmpMessage,
+ 2*sizeof(NvU32) );
+ }
+ else
+ {
+ HandlePortMessage(hPort->hRmDevice, (NvU32*)s_TransportInfo.pReceiveMem);
+ }
+ }
+
+#if LOOPBACK_PROFILE
+ if (hPort->bLoopTest)
+ {
+# if NV_IS_AVP
+ ((NvU32*)pMessageBuffer)[LOOP_AVP_RECV_INDEX] = *s_TransportInfo.pTimer;
+# else
+ ((NvU32*)pMessageBuffer)[LOOP_CPU_RECV_INDEX] = *s_TransportInfo.pTimer;
+# endif
+ }
+#endif
+
+ NvOsMutexUnlock(s_TransportInfo.mutex);
+
+ return NvSuccess;
+}
+
+void
+NvRmTransportGetPortName(
+ NvRmTransportHandle hPort,
+ NvU8 *PortName,
+ NvU32 PortNameSize )
+{
+ NvU32 len;
+
+ NV_ASSERT(hPort);
+ NV_ASSERT(PortName);
+
+ len = NvOsStrlen(hPort->PortName);
+ if (len >= PortNameSize)
+ {
+ NV_ASSERT(!" RM Transport: Port Name too long. ");
+ }
+
+ NvOsStrncpy((char *)PortName, hPort->PortName, PortNameSize);
+}
+
diff --git a/arch/arm/mach-tegra/nvrm/dispatch/Makefile b/arch/arm/mach-tegra/nvrm/dispatch/Makefile
index 959155944f47..dd1710b2b750 100644
--- a/arch/arm/mach-tegra/nvrm/dispatch/Makefile
+++ b/arch/arm/mach-tegra/nvrm/dispatch/Makefile
@@ -26,3 +26,5 @@ obj-y += nvrm_pmu_dispatch.o
obj-y += nvrm_keylist_dispatch.o
obj-y += nvrm_pcie_dispatch.o
obj-y += nvrm_memctrl_dispatch.o
+obj-y += nvrm_transport_dispatch.o
+obj-y += nvrm_xpc_dispatch.o
diff --git a/arch/arm/mach-tegra/nvrm/dispatch/NvRm_Dispatch.c b/arch/arm/mach-tegra/nvrm/dispatch/NvRm_Dispatch.c
index e8ea4ee5be9e..c321c393b6cf 100644
--- a/arch/arm/mach-tegra/nvrm/dispatch/NvRm_Dispatch.c
+++ b/arch/arm/mach-tegra/nvrm/dispatch/NvRm_Dispatch.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009 NVIDIA Corporation.
+ * Copyright (c) 2009-2010 NVIDIA Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,6 +35,8 @@
#include "nvassert.h"
#include "nvidlcmd.h"
#include "nvreftrack.h"
+#include "nvrm_xpc.h"
+#include "nvrm_transport.h"
#include "nvrm_memctrl.h"
#include "nvrm_pcie.h"
#include "nvrm_pwm.h"
@@ -53,6 +55,8 @@
#include "nvrm_module.h"
#include "nvrm_memmgr.h"
#include "nvrm_init.h"
+NvError nvrm_xpc_Dispatch( NvU32 function, void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx );
+NvError nvrm_transport_Dispatch( NvU32 function, void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx );
NvError nvrm_memctrl_Dispatch( NvU32 function, void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx );
NvError nvrm_pcie_Dispatch( NvU32 function, void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx );
NvError nvrm_pwm_Dispatch( NvU32 function, void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx );
@@ -76,6 +80,8 @@ NvError nvrm_init_Dispatch( NvU32 function, void *InBuffer, NvU32 InSize, void *
typedef enum
{
NvRm_Invalid = 0,
+ NvRm_nvrm_xpc,
+ NvRm_nvrm_transport,
NvRm_nvrm_memctrl,
NvRm_nvrm_pcie,
NvRm_nvrm_pwm,
@@ -108,6 +114,8 @@ typedef struct NvIdlDispatchTableRec
static NvIdlDispatchTable gs_DispatchTable[] =
{
+ { NvRm_nvrm_xpc, nvrm_xpc_Dispatch },
+ { NvRm_nvrm_transport, nvrm_transport_Dispatch },
{ NvRm_nvrm_memctrl, nvrm_memctrl_Dispatch },
{ NvRm_nvrm_pcie, nvrm_pcie_Dispatch },
{ NvRm_nvrm_pwm, nvrm_pwm_Dispatch },
@@ -149,3 +157,4 @@ NvError NvRm_Dispatch( void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutS
return table_[packid_ - 1].DispFunc( funcid_, InBuffer, InSize,
OutBuffer, OutSize, Ctx );
}
+
diff --git a/arch/arm/mach-tegra/nvrm/dispatch/nvrm_transport_dispatch.c b/arch/arm/mach-tegra/nvrm/dispatch/nvrm_transport_dispatch.c
new file mode 100644
index 000000000000..a37c39d2d8ae
--- /dev/null
+++ b/arch/arm/mach-tegra/nvrm/dispatch/nvrm_transport_dispatch.c
@@ -0,0 +1,657 @@
+
+#define NV_IDL_IS_DISPATCH
+
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvcommon.h"
+#include "nvos.h"
+#include "nvassert.h"
+#include "nvreftrack.h"
+#include "nvidlcmd.h"
+#include "nvrm_transport.h"
+
+#define OFFSET( s, e ) (NvU32)(void *)(&(((s*)0)->e))
+
+
+typedef struct NvRmTransportRecvMsg_in_t
+{
+ NvU32 package_;
+ NvU32 function_;
+ NvRmTransportHandle hTransport;
+ void* pMessageBuffer;
+ NvU32 MaxSize;
+} NV_ALIGN(4) NvRmTransportRecvMsg_in;
+
+typedef struct NvRmTransportRecvMsg_inout_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmTransportRecvMsg_inout;
+
+typedef struct NvRmTransportRecvMsg_out_t
+{
+ NvError ret_;
+ NvU32 pMessageSize;
+} NV_ALIGN(4) NvRmTransportRecvMsg_out;
+
+typedef struct NvRmTransportRecvMsg_params_t
+{
+ NvRmTransportRecvMsg_in in;
+ NvRmTransportRecvMsg_inout inout;
+ NvRmTransportRecvMsg_out out;
+} NvRmTransportRecvMsg_params;
+
+typedef struct NvRmTransportSendMsgInLP0_in_t
+{
+ NvU32 package_;
+ NvU32 function_;
+ NvRmTransportHandle hPort;
+ void* message;
+ NvU32 MessageSize;
+} NV_ALIGN(4) NvRmTransportSendMsgInLP0_in;
+
+typedef struct NvRmTransportSendMsgInLP0_inout_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmTransportSendMsgInLP0_inout;
+
+typedef struct NvRmTransportSendMsgInLP0_out_t
+{
+ NvError ret_;
+} NV_ALIGN(4) NvRmTransportSendMsgInLP0_out;
+
+typedef struct NvRmTransportSendMsgInLP0_params_t
+{
+ NvRmTransportSendMsgInLP0_in in;
+ NvRmTransportSendMsgInLP0_inout inout;
+ NvRmTransportSendMsgInLP0_out out;
+} NvRmTransportSendMsgInLP0_params;
+
+typedef struct NvRmTransportSendMsg_in_t
+{
+ NvU32 package_;
+ NvU32 function_;
+ NvRmTransportHandle hTransport;
+ void* pMessageBuffer;
+ NvU32 MessageSize;
+ NvU32 TimeoutMS;
+} NV_ALIGN(4) NvRmTransportSendMsg_in;
+
+typedef struct NvRmTransportSendMsg_inout_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmTransportSendMsg_inout;
+
+typedef struct NvRmTransportSendMsg_out_t
+{
+ NvError ret_;
+} NV_ALIGN(4) NvRmTransportSendMsg_out;
+
+typedef struct NvRmTransportSendMsg_params_t
+{
+ NvRmTransportSendMsg_in in;
+ NvRmTransportSendMsg_inout inout;
+ NvRmTransportSendMsg_out out;
+} NvRmTransportSendMsg_params;
+
+typedef struct NvRmTransportSetQueueDepth_in_t
+{
+ NvU32 package_;
+ NvU32 function_;
+ NvRmTransportHandle hTransport;
+ NvU32 MaxQueueDepth;
+ NvU32 MaxMessageSize;
+} NV_ALIGN(4) NvRmTransportSetQueueDepth_in;
+
+typedef struct NvRmTransportSetQueueDepth_inout_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmTransportSetQueueDepth_inout;
+
+typedef struct NvRmTransportSetQueueDepth_out_t
+{
+ NvError ret_;
+} NV_ALIGN(4) NvRmTransportSetQueueDepth_out;
+
+typedef struct NvRmTransportSetQueueDepth_params_t
+{
+ NvRmTransportSetQueueDepth_in in;
+ NvRmTransportSetQueueDepth_inout inout;
+ NvRmTransportSetQueueDepth_out out;
+} NvRmTransportSetQueueDepth_params;
+
+typedef struct NvRmTransportConnect_in_t
+{
+ NvU32 package_;
+ NvU32 function_;
+ NvRmTransportHandle hTransport;
+ NvU32 TimeoutMS;
+} NV_ALIGN(4) NvRmTransportConnect_in;
+
+typedef struct NvRmTransportConnect_inout_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmTransportConnect_inout;
+
+typedef struct NvRmTransportConnect_out_t
+{
+ NvError ret_;
+} NV_ALIGN(4) NvRmTransportConnect_out;
+
+typedef struct NvRmTransportConnect_params_t
+{
+ NvRmTransportConnect_in in;
+ NvRmTransportConnect_inout inout;
+ NvRmTransportConnect_out out;
+} NvRmTransportConnect_params;
+
+typedef struct NvRmTransportWaitForConnect_in_t
+{
+ NvU32 package_;
+ NvU32 function_;
+ NvRmTransportHandle hTransport;
+ NvU32 TimeoutMS;
+} NV_ALIGN(4) NvRmTransportWaitForConnect_in;
+
+typedef struct NvRmTransportWaitForConnect_inout_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmTransportWaitForConnect_inout;
+
+typedef struct NvRmTransportWaitForConnect_out_t
+{
+ NvError ret_;
+} NV_ALIGN(4) NvRmTransportWaitForConnect_out;
+
+typedef struct NvRmTransportWaitForConnect_params_t
+{
+ NvRmTransportWaitForConnect_in in;
+ NvRmTransportWaitForConnect_inout inout;
+ NvRmTransportWaitForConnect_out out;
+} NvRmTransportWaitForConnect_params;
+
+typedef struct NvRmTransportDeInit_in_t
+{
+ NvU32 package_;
+ NvU32 function_;
+ NvRmDeviceHandle hRmDevice;
+} NV_ALIGN(4) NvRmTransportDeInit_in;
+
+typedef struct NvRmTransportDeInit_inout_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmTransportDeInit_inout;
+
+typedef struct NvRmTransportDeInit_out_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmTransportDeInit_out;
+
+typedef struct NvRmTransportDeInit_params_t
+{
+ NvRmTransportDeInit_in in;
+ NvRmTransportDeInit_inout inout;
+ NvRmTransportDeInit_out out;
+} NvRmTransportDeInit_params;
+
+typedef struct NvRmTransportInit_in_t
+{
+ NvU32 package_;
+ NvU32 function_;
+ NvRmDeviceHandle hRmDevice;
+} NV_ALIGN(4) NvRmTransportInit_in;
+
+typedef struct NvRmTransportInit_inout_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmTransportInit_inout;
+
+typedef struct NvRmTransportInit_out_t
+{
+ NvError ret_;
+} NV_ALIGN(4) NvRmTransportInit_out;
+
+typedef struct NvRmTransportInit_params_t
+{
+ NvRmTransportInit_in in;
+ NvRmTransportInit_inout inout;
+ NvRmTransportInit_out out;
+} NvRmTransportInit_params;
+
+typedef struct NvRmTransportClose_in_t
+{
+ NvU32 package_;
+ NvU32 function_;
+ NvRmTransportHandle hTransport;
+} NV_ALIGN(4) NvRmTransportClose_in;
+
+typedef struct NvRmTransportClose_inout_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmTransportClose_inout;
+
+typedef struct NvRmTransportClose_out_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmTransportClose_out;
+
+typedef struct NvRmTransportClose_params_t
+{
+ NvRmTransportClose_in in;
+ NvRmTransportClose_inout inout;
+ NvRmTransportClose_out out;
+} NvRmTransportClose_params;
+
+typedef struct NvRmTransportGetPortName_in_t
+{
+ NvU32 package_;
+ NvU32 function_;
+ NvRmTransportHandle hTransport;
+ NvU8 * PortName;
+ NvU32 PortNameSize;
+} NV_ALIGN(4) NvRmTransportGetPortName_in;
+
+typedef struct NvRmTransportGetPortName_inout_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmTransportGetPortName_inout;
+
+typedef struct NvRmTransportGetPortName_out_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmTransportGetPortName_out;
+
+typedef struct NvRmTransportGetPortName_params_t
+{
+ NvRmTransportGetPortName_in in;
+ NvRmTransportGetPortName_inout inout;
+ NvRmTransportGetPortName_out out;
+} NvRmTransportGetPortName_params;
+
+typedef struct NvRmTransportOpen_in_t
+{
+ NvU32 package_;
+ NvU32 function_;
+ NvRmDeviceHandle hRmDevice;
+ char * pPortName_data;
+ NvU32 pPortName_len;
+ NvOsSemaphoreHandle RecvMessageSemaphore;
+} NV_ALIGN(4) NvRmTransportOpen_in;
+
+typedef struct NvRmTransportOpen_inout_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmTransportOpen_inout;
+
+typedef struct NvRmTransportOpen_out_t
+{
+ NvError ret_;
+ NvRmTransportHandle phTransport;
+} NV_ALIGN(4) NvRmTransportOpen_out;
+
+typedef struct NvRmTransportOpen_params_t
+{
+ NvRmTransportOpen_in in;
+ NvRmTransportOpen_inout inout;
+ NvRmTransportOpen_out out;
+} NvRmTransportOpen_params;
+
+static NvError NvRmTransportRecvMsg_dispatch_( void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+ NvRmTransportRecvMsg_in *p_in;
+ NvRmTransportRecvMsg_out *p_out;
+ void* pMessageBuffer = NULL;
+
+ p_in = (NvRmTransportRecvMsg_in *)InBuffer;
+ p_out = (NvRmTransportRecvMsg_out *)((NvU8 *)OutBuffer + OFFSET(NvRmTransportRecvMsg_params, out) - OFFSET(NvRmTransportRecvMsg_params, inout));
+
+ if( p_in->MaxSize && p_in->pMessageBuffer )
+ {
+ pMessageBuffer = (void* )NvOsAlloc( p_in->MaxSize );
+ if( !pMessageBuffer )
+ {
+ err_ = NvError_InsufficientMemory;
+ goto clean;
+ }
+ }
+
+ p_out->ret_ = NvRmTransportRecvMsg( p_in->hTransport, pMessageBuffer, p_in->MaxSize, &p_out->pMessageSize );
+
+ if(p_in->pMessageBuffer && pMessageBuffer)
+ {
+ err_ = NvOsCopyOut( p_in->pMessageBuffer, pMessageBuffer, p_in->MaxSize );
+ if( err_ != NvSuccess )
+ {
+ err_ = NvError_BadParameter;
+ }
+ }
+clean:
+ NvOsFree( pMessageBuffer );
+ return err_;
+}
+
+static NvError NvRmTransportSendMsgInLP0_dispatch_( void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+ NvRmTransportSendMsgInLP0_in *p_in;
+ NvRmTransportSendMsgInLP0_out *p_out;
+ void* message = NULL;
+
+ p_in = (NvRmTransportSendMsgInLP0_in *)InBuffer;
+ p_out = (NvRmTransportSendMsgInLP0_out *)((NvU8 *)OutBuffer + OFFSET(NvRmTransportSendMsgInLP0_params, out) - OFFSET(NvRmTransportSendMsgInLP0_params, inout));
+
+ if( p_in->MessageSize && p_in->message )
+ {
+ message = (void* )NvOsAlloc( p_in->MessageSize );
+ if( !message )
+ {
+ err_ = NvError_InsufficientMemory;
+ goto clean;
+ }
+ if( p_in->message )
+ {
+ err_ = NvOsCopyIn( message, p_in->message, p_in->MessageSize );
+ if( err_ != NvSuccess )
+ {
+ err_ = NvError_BadParameter;
+ goto clean;
+ }
+ }
+ }
+
+ p_out->ret_ = NvRmTransportSendMsgInLP0( p_in->hPort, message, p_in->MessageSize );
+
+clean:
+ NvOsFree( message );
+ return err_;
+}
+
+static NvError NvRmTransportSendMsg_dispatch_( void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+ NvRmTransportSendMsg_in *p_in;
+ NvRmTransportSendMsg_out *p_out;
+ void* pMessageBuffer = NULL;
+
+ p_in = (NvRmTransportSendMsg_in *)InBuffer;
+ p_out = (NvRmTransportSendMsg_out *)((NvU8 *)OutBuffer + OFFSET(NvRmTransportSendMsg_params, out) - OFFSET(NvRmTransportSendMsg_params, inout));
+
+ if( p_in->MessageSize && p_in->pMessageBuffer )
+ {
+ pMessageBuffer = (void* )NvOsAlloc( p_in->MessageSize );
+ if( !pMessageBuffer )
+ {
+ err_ = NvError_InsufficientMemory;
+ goto clean;
+ }
+ if( p_in->pMessageBuffer )
+ {
+ err_ = NvOsCopyIn( pMessageBuffer, p_in->pMessageBuffer, p_in->MessageSize );
+ if( err_ != NvSuccess )
+ {
+ err_ = NvError_BadParameter;
+ goto clean;
+ }
+ }
+ }
+
+ p_out->ret_ = NvRmTransportSendMsg( p_in->hTransport, pMessageBuffer, p_in->MessageSize, p_in->TimeoutMS );
+
+clean:
+ NvOsFree( pMessageBuffer );
+ return err_;
+}
+
+static NvError NvRmTransportSetQueueDepth_dispatch_( void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+ NvRmTransportSetQueueDepth_in *p_in;
+ NvRmTransportSetQueueDepth_out *p_out;
+
+ p_in = (NvRmTransportSetQueueDepth_in *)InBuffer;
+ p_out = (NvRmTransportSetQueueDepth_out *)((NvU8 *)OutBuffer + OFFSET(NvRmTransportSetQueueDepth_params, out) - OFFSET(NvRmTransportSetQueueDepth_params, inout));
+
+
+ p_out->ret_ = NvRmTransportSetQueueDepth( p_in->hTransport, p_in->MaxQueueDepth, p_in->MaxMessageSize );
+
+ return err_;
+}
+
+static NvError NvRmTransportConnect_dispatch_( void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+ NvRmTransportConnect_in *p_in;
+ NvRmTransportConnect_out *p_out;
+
+ p_in = (NvRmTransportConnect_in *)InBuffer;
+ p_out = (NvRmTransportConnect_out *)((NvU8 *)OutBuffer + OFFSET(NvRmTransportConnect_params, out) - OFFSET(NvRmTransportConnect_params, inout));
+
+
+ p_out->ret_ = NvRmTransportConnect( p_in->hTransport, p_in->TimeoutMS );
+
+ return err_;
+}
+
+static NvError NvRmTransportWaitForConnect_dispatch_( void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+ NvRmTransportWaitForConnect_in *p_in;
+ NvRmTransportWaitForConnect_out *p_out;
+
+ p_in = (NvRmTransportWaitForConnect_in *)InBuffer;
+ p_out = (NvRmTransportWaitForConnect_out *)((NvU8 *)OutBuffer + OFFSET(NvRmTransportWaitForConnect_params, out) - OFFSET(NvRmTransportWaitForConnect_params, inout));
+
+
+ p_out->ret_ = NvRmTransportWaitForConnect( p_in->hTransport, p_in->TimeoutMS );
+
+ return err_;
+}
+
+static NvError NvRmTransportDeInit_dispatch_( void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+ NvRmTransportDeInit_in *p_in;
+
+ p_in = (NvRmTransportDeInit_in *)InBuffer;
+
+
+ NvRmTransportDeInit( p_in->hRmDevice );
+
+ return err_;
+}
+
+static NvError NvRmTransportInit_dispatch_( void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+ NvRmTransportInit_in *p_in;
+ NvRmTransportInit_out *p_out;
+
+ p_in = (NvRmTransportInit_in *)InBuffer;
+ p_out = (NvRmTransportInit_out *)((NvU8 *)OutBuffer + OFFSET(NvRmTransportInit_params, out) - OFFSET(NvRmTransportInit_params, inout));
+
+
+ p_out->ret_ = NvRmTransportInit( p_in->hRmDevice );
+
+ return err_;
+}
+
+static NvError NvRmTransportClose_dispatch_( void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+ NvRmTransportClose_in *p_in;
+
+ p_in = (NvRmTransportClose_in *)InBuffer;
+
+
+ NvRmTransportClose( p_in->hTransport );
+
+ return err_;
+}
+
+static NvError NvRmTransportGetPortName_dispatch_( void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+ NvRmTransportGetPortName_in *p_in;
+ NvU8 *PortName = NULL;
+
+ p_in = (NvRmTransportGetPortName_in *)InBuffer;
+
+ if( p_in->PortNameSize && p_in->PortName )
+ {
+ PortName = (NvU8 *)NvOsAlloc( p_in->PortNameSize * sizeof( NvU8 ) );
+ if( !PortName )
+ {
+ err_ = NvError_InsufficientMemory;
+ goto clean;
+ }
+ if( p_in->PortName )
+ {
+ err_ = NvOsCopyIn( PortName, p_in->PortName, p_in->PortNameSize * sizeof( NvU8 ) );
+ if( err_ != NvSuccess )
+ {
+ err_ = NvError_BadParameter;
+ goto clean;
+ }
+ }
+ }
+
+ NvRmTransportGetPortName( p_in->hTransport, PortName, p_in->PortNameSize );
+
+ if(p_in->PortName && PortName)
+ {
+ err_ = NvOsCopyOut( p_in->PortName, PortName, p_in->PortNameSize * sizeof( NvU8 ) );
+ if( err_ != NvSuccess )
+ {
+ err_ = NvError_BadParameter;
+ }
+ }
+clean:
+ NvOsFree( PortName );
+ return err_;
+}
+
+static NvError NvRmTransportOpen_dispatch_( void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+ NvRmTransportOpen_in *p_in;
+ NvRmTransportOpen_out *p_out;
+ char *pPortName = NULL;
+ NvOsSemaphoreHandle RecvMessageSemaphore = NULL;
+
+ p_in = (NvRmTransportOpen_in *)InBuffer;
+ p_out = (NvRmTransportOpen_out *)((NvU8 *)OutBuffer + OFFSET(NvRmTransportOpen_params, out) - OFFSET(NvRmTransportOpen_params, inout));
+
+ if( p_in->pPortName_len )
+ {
+ pPortName = NvOsAlloc( p_in->pPortName_len );
+ if( !pPortName )
+ {
+ err_ = NvError_InsufficientMemory;
+ goto clean;
+ }
+ err_ = NvOsCopyIn( pPortName, p_in->pPortName_data, p_in->pPortName_len );
+ if( err_ != NvSuccess )
+ {
+ err_ = NvError_BadParameter;
+ goto clean;
+ }
+ if( pPortName[p_in->pPortName_len - 1] != 0 )
+ {
+ err_ = NvError_BadParameter;
+ goto clean;
+ }
+ }
+ if( p_in->RecvMessageSemaphore )
+ {
+ err_ = NvOsSemaphoreUnmarshal( p_in->RecvMessageSemaphore, &RecvMessageSemaphore );
+ if( err_ != NvSuccess )
+ {
+ err_ = NvError_BadParameter;
+ goto clean;
+ }
+ }
+
+ p_out->ret_ = NvRmTransportOpen( p_in->hRmDevice, pPortName, RecvMessageSemaphore, &p_out->phTransport );
+
+clean:
+ NvOsFree( pPortName );
+ NvOsSemaphoreDestroy( RecvMessageSemaphore );
+ return err_;
+}
+
+NvError nvrm_transport_Dispatch( NvU32 function, void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx );
+NvError nvrm_transport_Dispatch( NvU32 function, void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+
+ switch( function ) {
+ case 10:
+ err_ = NvRmTransportRecvMsg_dispatch_( InBuffer, InSize, OutBuffer, OutSize, Ctx );
+ break;
+ case 9:
+ err_ = NvRmTransportSendMsgInLP0_dispatch_( InBuffer, InSize, OutBuffer, OutSize, Ctx );
+ break;
+ case 8:
+ err_ = NvRmTransportSendMsg_dispatch_( InBuffer, InSize, OutBuffer, OutSize, Ctx );
+ break;
+ case 7:
+ err_ = NvRmTransportSetQueueDepth_dispatch_( InBuffer, InSize, OutBuffer, OutSize, Ctx );
+ break;
+ case 6:
+ err_ = NvRmTransportConnect_dispatch_( InBuffer, InSize, OutBuffer, OutSize, Ctx );
+ break;
+ case 5:
+ err_ = NvRmTransportWaitForConnect_dispatch_( InBuffer, InSize, OutBuffer, OutSize, Ctx );
+ break;
+ case 4:
+ err_ = NvRmTransportDeInit_dispatch_( InBuffer, InSize, OutBuffer, OutSize, Ctx );
+ break;
+ case 3:
+ err_ = NvRmTransportInit_dispatch_( InBuffer, InSize, OutBuffer, OutSize, Ctx );
+ break;
+ case 2:
+ err_ = NvRmTransportClose_dispatch_( InBuffer, InSize, OutBuffer, OutSize, Ctx );
+ break;
+ case 1:
+ err_ = NvRmTransportGetPortName_dispatch_( InBuffer, InSize, OutBuffer, OutSize, Ctx );
+ break;
+ case 0:
+ err_ = NvRmTransportOpen_dispatch_( InBuffer, InSize, OutBuffer, OutSize, Ctx );
+ break;
+ default:
+ err_ = NvError_BadParameter;
+ break;
+ }
+
+ return err_;
+}
diff --git a/arch/arm/mach-tegra/nvrm/dispatch/nvrm_xpc_dispatch.c b/arch/arm/mach-tegra/nvrm/dispatch/nvrm_xpc_dispatch.c
new file mode 100644
index 000000000000..16b98ede32e0
--- /dev/null
+++ b/arch/arm/mach-tegra/nvrm/dispatch/nvrm_xpc_dispatch.c
@@ -0,0 +1,348 @@
+
+#define NV_IDL_IS_DISPATCH
+
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvcommon.h"
+#include "nvos.h"
+#include "nvassert.h"
+#include "nvreftrack.h"
+#include "nvidlcmd.h"
+#include "nvrm_xpc.h"
+
+#define OFFSET( s, e ) (NvU32)(void *)(&(((s*)0)->e))
+
+
+typedef struct NvRmXpcModuleRelease_in_t
+{
+ NvU32 package_;
+ NvU32 function_;
+ NvRmModuleID modId;
+} NV_ALIGN(4) NvRmXpcModuleRelease_in;
+
+typedef struct NvRmXpcModuleRelease_inout_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmXpcModuleRelease_inout;
+
+typedef struct NvRmXpcModuleRelease_out_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmXpcModuleRelease_out;
+
+typedef struct NvRmXpcModuleRelease_params_t
+{
+ NvRmXpcModuleRelease_in in;
+ NvRmXpcModuleRelease_inout inout;
+ NvRmXpcModuleRelease_out out;
+} NvRmXpcModuleRelease_params;
+
+typedef struct NvRmXpcModuleAcquire_in_t
+{
+ NvU32 package_;
+ NvU32 function_;
+ NvRmModuleID modId;
+} NV_ALIGN(4) NvRmXpcModuleAcquire_in;
+
+typedef struct NvRmXpcModuleAcquire_inout_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmXpcModuleAcquire_inout;
+
+typedef struct NvRmXpcModuleAcquire_out_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmXpcModuleAcquire_out;
+
+typedef struct NvRmXpcModuleAcquire_params_t
+{
+ NvRmXpcModuleAcquire_in in;
+ NvRmXpcModuleAcquire_inout inout;
+ NvRmXpcModuleAcquire_out out;
+} NvRmXpcModuleAcquire_params;
+
+typedef struct NvRmXpcInitArbSemaSystem_in_t
+{
+ NvU32 package_;
+ NvU32 function_;
+ NvRmDeviceHandle hDevice;
+} NV_ALIGN(4) NvRmXpcInitArbSemaSystem_in;
+
+typedef struct NvRmXpcInitArbSemaSystem_inout_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmXpcInitArbSemaSystem_inout;
+
+typedef struct NvRmXpcInitArbSemaSystem_out_t
+{
+ NvError ret_;
+} NV_ALIGN(4) NvRmXpcInitArbSemaSystem_out;
+
+typedef struct NvRmXpcInitArbSemaSystem_params_t
+{
+ NvRmXpcInitArbSemaSystem_in in;
+ NvRmXpcInitArbSemaSystem_inout inout;
+ NvRmXpcInitArbSemaSystem_out out;
+} NvRmXpcInitArbSemaSystem_params;
+
+typedef struct NvRmPrivXpcGetMessage_in_t
+{
+ NvU32 package_;
+ NvU32 function_;
+ NvRmPrivXpcMessageHandle hXpcMessage;
+} NV_ALIGN(4) NvRmPrivXpcGetMessage_in;
+
+typedef struct NvRmPrivXpcGetMessage_inout_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmPrivXpcGetMessage_inout;
+
+typedef struct NvRmPrivXpcGetMessage_out_t
+{
+ NvU32 ret_;
+} NV_ALIGN(4) NvRmPrivXpcGetMessage_out;
+
+typedef struct NvRmPrivXpcGetMessage_params_t
+{
+ NvRmPrivXpcGetMessage_in in;
+ NvRmPrivXpcGetMessage_inout inout;
+ NvRmPrivXpcGetMessage_out out;
+} NvRmPrivXpcGetMessage_params;
+
+typedef struct NvRmPrivXpcSendMessage_in_t
+{
+ NvU32 package_;
+ NvU32 function_;
+ NvRmPrivXpcMessageHandle hXpcMessage;
+ NvU32 data;
+} NV_ALIGN(4) NvRmPrivXpcSendMessage_in;
+
+typedef struct NvRmPrivXpcSendMessage_inout_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmPrivXpcSendMessage_inout;
+
+typedef struct NvRmPrivXpcSendMessage_out_t
+{
+ NvError ret_;
+} NV_ALIGN(4) NvRmPrivXpcSendMessage_out;
+
+typedef struct NvRmPrivXpcSendMessage_params_t
+{
+ NvRmPrivXpcSendMessage_in in;
+ NvRmPrivXpcSendMessage_inout inout;
+ NvRmPrivXpcSendMessage_out out;
+} NvRmPrivXpcSendMessage_params;
+
+typedef struct NvRmPrivXpcDestroy_in_t
+{
+ NvU32 package_;
+ NvU32 function_;
+ NvRmPrivXpcMessageHandle hXpcMessage;
+} NV_ALIGN(4) NvRmPrivXpcDestroy_in;
+
+typedef struct NvRmPrivXpcDestroy_inout_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmPrivXpcDestroy_inout;
+
+typedef struct NvRmPrivXpcDestroy_out_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmPrivXpcDestroy_out;
+
+typedef struct NvRmPrivXpcDestroy_params_t
+{
+ NvRmPrivXpcDestroy_in in;
+ NvRmPrivXpcDestroy_inout inout;
+ NvRmPrivXpcDestroy_out out;
+} NvRmPrivXpcDestroy_params;
+
+typedef struct NvRmPrivXpcCreate_in_t
+{
+ NvU32 package_;
+ NvU32 function_;
+ NvRmDeviceHandle hDevice;
+} NV_ALIGN(4) NvRmPrivXpcCreate_in;
+
+typedef struct NvRmPrivXpcCreate_inout_t
+{
+ NvU32 dummy_;
+} NV_ALIGN(4) NvRmPrivXpcCreate_inout;
+
+typedef struct NvRmPrivXpcCreate_out_t
+{
+ NvError ret_;
+ NvRmPrivXpcMessageHandle phXpcMessage;
+} NV_ALIGN(4) NvRmPrivXpcCreate_out;
+
+typedef struct NvRmPrivXpcCreate_params_t
+{
+ NvRmPrivXpcCreate_in in;
+ NvRmPrivXpcCreate_inout inout;
+ NvRmPrivXpcCreate_out out;
+} NvRmPrivXpcCreate_params;
+
+static NvError NvRmXpcModuleRelease_dispatch_( void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+ NvRmXpcModuleRelease_in *p_in;
+
+ p_in = (NvRmXpcModuleRelease_in *)InBuffer;
+
+
+ NvRmXpcModuleRelease( p_in->modId );
+
+ return err_;
+}
+
+static NvError NvRmXpcModuleAcquire_dispatch_( void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+ NvRmXpcModuleAcquire_in *p_in;
+
+ p_in = (NvRmXpcModuleAcquire_in *)InBuffer;
+
+
+ NvRmXpcModuleAcquire( p_in->modId );
+
+ return err_;
+}
+
+static NvError NvRmXpcInitArbSemaSystem_dispatch_( void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+ NvRmXpcInitArbSemaSystem_in *p_in;
+ NvRmXpcInitArbSemaSystem_out *p_out;
+
+ p_in = (NvRmXpcInitArbSemaSystem_in *)InBuffer;
+ p_out = (NvRmXpcInitArbSemaSystem_out *)((NvU8 *)OutBuffer + OFFSET(NvRmXpcInitArbSemaSystem_params, out) - OFFSET(NvRmXpcInitArbSemaSystem_params, inout));
+
+
+ p_out->ret_ = NvRmXpcInitArbSemaSystem( p_in->hDevice );
+
+ return err_;
+}
+
+static NvError NvRmPrivXpcGetMessage_dispatch_( void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+ NvRmPrivXpcGetMessage_in *p_in;
+ NvRmPrivXpcGetMessage_out *p_out;
+
+ p_in = (NvRmPrivXpcGetMessage_in *)InBuffer;
+ p_out = (NvRmPrivXpcGetMessage_out *)((NvU8 *)OutBuffer + OFFSET(NvRmPrivXpcGetMessage_params, out) - OFFSET(NvRmPrivXpcGetMessage_params, inout));
+
+
+ p_out->ret_ = NvRmPrivXpcGetMessage( p_in->hXpcMessage );
+
+ return err_;
+}
+
+static NvError NvRmPrivXpcSendMessage_dispatch_( void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+ NvRmPrivXpcSendMessage_in *p_in;
+ NvRmPrivXpcSendMessage_out *p_out;
+
+ p_in = (NvRmPrivXpcSendMessage_in *)InBuffer;
+ p_out = (NvRmPrivXpcSendMessage_out *)((NvU8 *)OutBuffer + OFFSET(NvRmPrivXpcSendMessage_params, out) - OFFSET(NvRmPrivXpcSendMessage_params, inout));
+
+
+ p_out->ret_ = NvRmPrivXpcSendMessage( p_in->hXpcMessage, p_in->data );
+
+ return err_;
+}
+
+static NvError NvRmPrivXpcDestroy_dispatch_( void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+ NvRmPrivXpcDestroy_in *p_in;
+
+ p_in = (NvRmPrivXpcDestroy_in *)InBuffer;
+
+
+ NvRmPrivXpcDestroy( p_in->hXpcMessage );
+
+ return err_;
+}
+
+static NvError NvRmPrivXpcCreate_dispatch_( void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+ NvRmPrivXpcCreate_in *p_in;
+ NvRmPrivXpcCreate_out *p_out;
+
+ p_in = (NvRmPrivXpcCreate_in *)InBuffer;
+ p_out = (NvRmPrivXpcCreate_out *)((NvU8 *)OutBuffer + OFFSET(NvRmPrivXpcCreate_params, out) - OFFSET(NvRmPrivXpcCreate_params, inout));
+
+
+ p_out->ret_ = NvRmPrivXpcCreate( p_in->hDevice, &p_out->phXpcMessage );
+
+ return err_;
+}
+
+NvError nvrm_xpc_Dispatch( NvU32 function, void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx );
+NvError nvrm_xpc_Dispatch( NvU32 function, void *InBuffer, NvU32 InSize, void *OutBuffer, NvU32 OutSize, NvDispatchCtx* Ctx )
+{
+ NvError err_ = NvSuccess;
+
+ switch( function ) {
+ case 6:
+ err_ = NvRmXpcModuleRelease_dispatch_( InBuffer, InSize, OutBuffer, OutSize, Ctx );
+ break;
+ case 5:
+ err_ = NvRmXpcModuleAcquire_dispatch_( InBuffer, InSize, OutBuffer, OutSize, Ctx );
+ break;
+ case 4:
+ err_ = NvRmXpcInitArbSemaSystem_dispatch_( InBuffer, InSize, OutBuffer, OutSize, Ctx );
+ break;
+ case 3:
+ err_ = NvRmPrivXpcGetMessage_dispatch_( InBuffer, InSize, OutBuffer, OutSize, Ctx );
+ break;
+ case 2:
+ err_ = NvRmPrivXpcSendMessage_dispatch_( InBuffer, InSize, OutBuffer, OutSize, Ctx );
+ break;
+ case 1:
+ err_ = NvRmPrivXpcDestroy_dispatch_( InBuffer, InSize, OutBuffer, OutSize, Ctx );
+ break;
+ case 0:
+ err_ = NvRmPrivXpcCreate_dispatch_( InBuffer, InSize, OutBuffer, OutSize, Ctx );
+ break;
+ default:
+ err_ = NvError_BadParameter;
+ break;
+ }
+
+ return err_;
+}