summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/nv
diff options
context:
space:
mode:
authorGary King <gking@nvidia.com>2010-09-09 17:04:17 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2010-10-19 13:35:02 -0700
commitda33d5cff9a52787290e2cabf0da2cc7ab9dba5a (patch)
treee1a3e6f180cfb1d26b9f77e2f216f69b289cd821 /arch/arm/mach-tegra/nv
parent760138ecbcbeb79d5618075a460352a32f8f65aa (diff)
[ARM] tegra: nvrm: implement nvrm transport on new nvmap interface
Change-Id: I5bdff4602ba53cfd6b6710923ce0e4f93831f29e
Diffstat (limited to 'arch/arm/mach-tegra/nv')
-rw-r--r--arch/arm/mach-tegra/nv/nvrm/core/ap15/ap15rm_avp_service.c162
-rw-r--r--arch/arm/mach-tegra/nv/nvrm/core/common/nvrm_moduleloader.c128
-rw-r--r--arch/arm/mach-tegra/nv/nvrm/core/common/nvrm_transport.c282
-rw-r--r--arch/arm/mach-tegra/nv/nvrm_user.c5
4 files changed, 256 insertions, 321 deletions
diff --git a/arch/arm/mach-tegra/nv/nvrm/core/ap15/ap15rm_avp_service.c b/arch/arm/mach-tegra/nv/nvrm/core/ap15/ap15rm_avp_service.c
index f632410cd9a7..674a0cf8ae0d 100644
--- a/arch/arm/mach-tegra/nv/nvrm/core/ap15/ap15rm_avp_service.c
+++ b/arch/arm/mach-tegra/nv/nvrm/core/ap15/ap15rm_avp_service.c
@@ -40,6 +40,9 @@
#include <linux/delay.h>
#include <linux/dma-mapping.h>
+#include <mach/nvmap.h>
+
+#include "../../../../../../../drivers/video/tegra/nvmap/nvmap.h"
#include "nvcommon.h"
#include "nvassert.h"
#include "nvrm_drf.h"
@@ -57,13 +60,67 @@
#include "mach/io.h"
#include "mach/iomap.h"
+extern struct nvmap_client *s_AvpClient;
+
#define NV_USE_AOS 1
-void NvRmPrivProcessMessage(NvRmRPCHandle hRPCHandle, char *pRecvMessage, int messageLength)
+static void HandleCreateMessage(const NvRmMessage_HandleCreat *req,
+ NvRmMessage_HandleCreatResponse *resp)
{
- NvError Error = NvSuccess;
- NvRmMemHandle hMem;
+ struct nvmap_handle_ref *ref;
+
+ resp->msg = NvRmMsg_MemHandleCreate_Response;
+ ref = nvmap_create_handle(s_AvpClient, req->size);
+ if (IS_ERR(ref)) {
+ resp->error = NvError_InsufficientMemory;
+ } else {
+ resp->error = NvSuccess;
+ resp->hMem = (NvRmMemHandle)nvmap_ref_to_id(ref);
+ }
+}
+static void HandleAllocMessage(const NvRmMessage_MemAlloc *req, NvRmMessage_Response *resp)
+{
+ struct nvmap_handle *handle;
+ unsigned int heap_mask = 0;
+ unsigned int i;
+ size_t align;
+ int err;
+
+ resp->msg = NvRmMsg_MemAlloc_Response;
+
+ if (!req->NumHeaps)
+ heap_mask = NVMAP_HEAP_CARVEOUT_GENERIC | NVMAP_HEAP_SYSMEM;
+
+ for (i = 0; i < req->NumHeaps; i++) {
+ if (req->Heaps[i] == NvRmHeap_GART)
+ heap_mask |= NVMAP_HEAP_IOVMM;
+ else if (req->Heaps[i] == NvRmHeap_IRam)
+ heap_mask |= NVMAP_HEAP_CARVEOUT_IRAM;
+ else if (req->Heaps[i] == NvRmHeap_External)
+ heap_mask |= NVMAP_HEAP_SYSMEM;
+ else if (req->Heaps[i] == NvRmHeap_ExternalCarveOut)
+ heap_mask |= NVMAP_HEAP_CARVEOUT_GENERIC;
+ }
+
+ handle = nvmap_get_handle_id(s_AvpClient, (unsigned long)req->hMem);
+ if (IS_ERR(handle)) {
+ resp->error = NvError_AccessDenied;
+ return;
+ }
+
+ align = max_t(size_t, L1_CACHE_BYTES, req->Alignment);
+ err = nvmap_alloc_handle_id(s_AvpClient, (unsigned long)req->hMem,
+ heap_mask, align, 0);
+ nvmap_handle_put(handle);
+
+ if (err)
+ resp->error = NvError_InsufficientMemory;
+ else
+ resp->error = NvSuccess;
+}
+void NvRmPrivProcessMessage(NvRmRPCHandle hRPCHandle, char *pRecvMessage, int messageLength)
+{
switch (*(NvRmMsg *)pRecvMessage) {
case NvRmMsg_MemHandleCreate:
@@ -72,17 +129,10 @@ void NvRmPrivProcessMessage(NvRmRPCHandle hRPCHandle, char *pRecvMessage, int me
NvRmMessage_HandleCreatResponse msgRHandleCreate;
msgHandleCreate = (NvRmMessage_HandleCreat*)pRecvMessage;
-
- msgRHandleCreate.msg = NvRmMsg_MemHandleCreate;
- Error = NvRmMemHandleCreate(hRPCHandle->hRmDevice,&hMem, msgHandleCreate->size);
- if (!Error) {
- msgRHandleCreate.hMem = hMem;
- }
- msgRHandleCreate.msg = NvRmMsg_MemHandleCreate_Response;
- msgRHandleCreate.error = Error;
-
+ HandleCreateMessage(msgHandleCreate, &msgRHandleCreate);
NvRmPrivRPCSendMsg(hRPCHandle, &msgRHandleCreate,
sizeof(msgRHandleCreate));
+ barrier();
}
break;
case NvRmMsg_MemHandleOpen:
@@ -91,7 +141,8 @@ void NvRmPrivProcessMessage(NvRmRPCHandle hRPCHandle, char *pRecvMessage, int me
{
NvRmMessage_HandleFree *msgHandleFree = NULL;
msgHandleFree = (NvRmMessage_HandleFree*)pRecvMessage;
- NvRmMemHandleFree(msgHandleFree->hMem);
+ nvmap_free_handle_id(s_AvpClient, (unsigned long)msgHandleFree->hMem);
+ barrier();
}
break;
case NvRmMsg_MemAlloc:
@@ -100,68 +151,79 @@ void NvRmPrivProcessMessage(NvRmRPCHandle hRPCHandle, char *pRecvMessage, int me
NvRmMessage_Response msgResponse;
msgMemAlloc = (NvRmMessage_MemAlloc*)pRecvMessage;
- Error = NvRmMemAlloc(msgMemAlloc->hMem,
- (msgMemAlloc->NumHeaps == 0) ? NULL : msgMemAlloc->Heaps,
- msgMemAlloc->NumHeaps,
- msgMemAlloc->Alignment,
- msgMemAlloc->Coherency);
- msgResponse.msg = NvRmMsg_MemAlloc_Response;
- msgResponse.error = Error;
-
+ HandleAllocMessage(msgMemAlloc, &msgResponse);
NvRmPrivRPCSendMsg(hRPCHandle, &msgResponse, sizeof(msgResponse));
+ barrier();
}
break;
case NvRmMsg_MemPin:
{
- NvRmMessage_Pin *msgHandleFree = NULL;
- NvRmMessage_PinResponse msgResponse;
- msgHandleFree = (NvRmMessage_Pin*)pRecvMessage;
-
- msgResponse.address = NvRmMemPin(msgHandleFree->hMem);
- msgResponse.msg = NvRmMsg_MemPin_Response;
-
- NvRmPrivRPCSendMsg(hRPCHandle, &msgResponse, sizeof(msgResponse));
+ NvRmMessage_Pin *msg;
+ NvRmMessage_PinResponse response;
+ unsigned long id;
+ int err;
+
+ msg = (NvRmMessage_Pin *)pRecvMessage;
+ id = (unsigned long)msg->hMem;
+ response.msg = NvRmMsg_MemPin_Response;
+
+ err = nvmap_pin_ids(s_AvpClient, 1, &id);
+ if (!err)
+ response.address = nvmap_handle_address(s_AvpClient, id);
+ else
+ response.address = 0xffffffff;
+
+ NvRmPrivRPCSendMsg(hRPCHandle, &response, sizeof(response));
+ barrier();
}
break;
case NvRmMsg_MemUnpin:
{
- NvRmMessage_HandleFree *msgHandleFree = NULL;
+ NvRmMessage_HandleFree *msg = NULL;
NvRmMessage_Response msgResponse;
- msgHandleFree = (NvRmMessage_HandleFree*)pRecvMessage;
+ unsigned long id;
- NvRmMemUnpin(msgHandleFree->hMem);
+ msg = (NvRmMessage_HandleFree*)pRecvMessage;
+ id = (unsigned long)msg->hMem;
+ nvmap_unpin_ids(s_AvpClient, 1, &id);
msgResponse.msg = NvRmMsg_MemUnpin_Response;
msgResponse.error = NvSuccess;
NvRmPrivRPCSendMsg(hRPCHandle, &msgResponse, sizeof(msgResponse));
+ barrier();
}
break;
case NvRmMsg_MemGetAddress:
{
- NvRmMessage_GetAddress *msgGetAddress = NULL;
- NvRmMessage_GetAddressResponse msgGetAddrResponse;
-
- msgGetAddress = (NvRmMessage_GetAddress*)pRecvMessage;
-
- msgGetAddrResponse.msg = NvRmMsg_MemGetAddress_Response;
- msgGetAddrResponse.address = NvRmMemGetAddress(msgGetAddress->hMem,msgGetAddress->Offset);
-
- NvRmPrivRPCSendMsg(hRPCHandle, &msgGetAddrResponse, sizeof(msgGetAddrResponse));
+ NvRmMessage_GetAddress *msg = NULL;
+ NvRmMessage_GetAddressResponse response;
+ unsigned long address;
+
+ msg = (NvRmMessage_GetAddress*)pRecvMessage;
+ address = nvmap_handle_address(s_AvpClient, (unsigned long)msg->hMem);
+ response.address = address + msg->Offset;
+ response.msg = NvRmMsg_MemGetAddress_Response;
+ NvRmPrivRPCSendMsg(hRPCHandle, &response, sizeof(response));
+ barrier();
}
break;
case NvRmMsg_HandleFromId :
{
- NvRmMessage_HandleFromId *msgHandleFromId = NULL;
- NvRmMessage_Response msgResponse;
- NvRmMemHandle hMem;
+ NvRmMessage_HandleFromId *msg = NULL;
+ struct nvmap_handle_ref *ref;
+ NvRmMessage_Response response;
- msgHandleFromId = (NvRmMessage_HandleFromId*)pRecvMessage;
+ msg = (NvRmMessage_HandleFromId*)pRecvMessage;
+ ref = nvmap_duplicate_handle_id(s_AvpClient, msg->id);
- msgResponse.msg = NvRmMsg_HandleFromId_Response;
- msgResponse.error = NvRmMemHandleFromId(msgHandleFromId->id, &hMem);
+ response.msg = NvRmMsg_HandleFromId_Response;
+ if (IS_ERR(ref))
+ response.error = NvError_InsufficientMemory;
+ else
+ response.error = NvSuccess;
- NvRmPrivRPCSendMsg(hRPCHandle, &msgResponse, sizeof(NvRmMessage_Response));
+ NvRmPrivRPCSendMsg(hRPCHandle, &response, sizeof(response));
}
break;
case NvRmMsg_PowerModuleClockControl:
@@ -267,8 +329,8 @@ void NvRmPrivProcessMessage(NvRmRPCHandle hRPCHandle, char *pRecvMessage, int me
NvOsDebugPrintf("AVP has been reset by WDT\n");
break;
default:
- panic("AVP Service::ProcessMessage: bad message");
- break;
+ panic("AVP Service::ProcessMessage: bad message");
+ break;
}
}
diff --git a/arch/arm/mach-tegra/nv/nvrm/core/common/nvrm_moduleloader.c b/arch/arm/mach-tegra/nv/nvrm/core/common/nvrm_moduleloader.c
index 695216c8fed3..bf79ce5a6d4b 100644
--- a/arch/arm/mach-tegra/nv/nvrm/core/common/nvrm_moduleloader.c
+++ b/arch/arm/mach-tegra/nv/nvrm/core/common/nvrm_moduleloader.c
@@ -36,6 +36,7 @@
#include <linux/platform_device.h>
#include <asm/cacheflush.h>
#include <asm/io.h>
+#include <mach/nvmap.h>
#include "nvcommon.h"
#include "nvassert.h"
@@ -62,7 +63,10 @@
static const struct firmware *s_FwEntry;
static NvRmRPCHandle s_RPCHandle = NULL;
-static NvRmMemHandle s_KernelImage = NULL;
+
+static struct nvmap_handle_ref *s_KernelImage = NULL;
+struct nvmap_client *s_AvpClient = NULL;
+
static NvError SendMsgDetachModule(NvRmLibraryHandle hLibHandle);
static NvError SendMsgAttachModule(
NvRmLibraryHandle hLibHandle,
@@ -330,8 +334,7 @@ NvError NvRmLoadLibraryEx(
NvRmLibraryHandle library = NULL;
NvError e = NvSuccess;
PrivateOsFileHandle hFile = NULL;
- NvRmMemHandle hMem = NULL;
- NvRmHeap loadHeap = NvRmHeap_ExternalCarveOut;
+ struct nvmap_handle_ref *staging = NULL;
void *loadAddr = NULL;
NvU32 len = 0;
NvU32 physAddr;
@@ -357,18 +360,27 @@ NvError NvRmLoadLibraryEx(
NV_CHECK_ERROR_CLEANUP(PrivateOsFopen(pLibName, NVOS_OPEN_READ, &hFile));
len = (NvU32)hFile->pend - (NvU32)hFile->pstart;
- NV_CHECK_ERROR_CLEANUP(NvRmMemHandleCreate(hDevice, &hMem, len));
-
- NV_CHECK_ERROR_CLEANUP(NvRmMemAlloc(hMem, &loadHeap, 1, L1_CACHE_BYTES,
- NvOsMemAttribute_WriteCombined));
-
- NV_CHECK_ERROR_CLEANUP(NvRmMemMap(hMem, 0, len, NVOS_MEM_READ_WRITE, &loadAddr));
-
- physAddr = NvRmMemPin(hMem);
+ staging = nvmap_alloc(s_AvpClient, len, L1_CACHE_BYTES,
+ NVMAP_HANDLE_WRITE_COMBINE);
+ if (IS_ERR(staging)) {
+ e = NvError_InsufficientMemory;
+ goto fail;
+ }
+ loadAddr = nvmap_mmap(staging);
+ if (!loadAddr) {
+ e = NvError_InsufficientMemory;
+ goto fail;
+ }
+ physAddr = nvmap_pin(s_AvpClient, staging);
+ if (IS_ERR((void*)physAddr)) {
+ e = NvError_InsufficientMemory;
+ goto fail;
+ }
NvOsMemcpy(loadAddr, hFile->pstart, len);
- NvOsFlushWriteCombineBuffer();
+ memcpy(loadAddr, hFile->pstart, len);
+ wmb();
NV_CHECK_ERROR_CLEANUP(SendMsgAttachModule(library, pArgs, physAddr, len,
IsApproachGreedy, sizeOfArgs));
@@ -376,11 +388,15 @@ NvError NvRmLoadLibraryEx(
fail:
if (loadAddr)
{
- NvRmMemUnpin(hMem);
- NvRmMemUnmap(hMem, loadAddr, len);
+ if (!IS_ERR((void*)physAddr))
+ nvmap_unpin(s_AvpClient, staging);
+
+ nvmap_munmap(staging, loadAddr);
}
- NvRmMemHandleFree(hMem);
+ if (!IS_ERR_OR_NULL(staging))
+ nvmap_free(s_AvpClient, staging);
+
if (hFile)
PrivateOsFclose(hFile);
@@ -546,7 +562,6 @@ void NvRmPrivXpcSendMsgAddress(void);
static NvError NvRmPrivInitAvp(NvRmDeviceHandle hRm)
{
u32 *stub_phys = &_tegra_avp_launcher_stub_data[AVP_LAUNCHER_MMU_PHYSICAL];
- NvRmHeap heaps[] = { NvRmHeap_External, NvRmHeap_ExternalCarveOut };
PrivateOsFileHandle kernel;
void *map = NULL;
NvError e;
@@ -556,21 +571,38 @@ static NvError NvRmPrivInitAvp(NvRmDeviceHandle hRm)
if (s_KernelImage)
return NvSuccess;
- NV_CHECK_ERROR_CLEANUP(NvRmMemHandleCreate(hRm, &s_KernelImage, SZ_1M));
- NV_CHECK_ERROR_CLEANUP(NvRmMemAlloc(s_KernelImage, heaps,
- NV_ARRAY_SIZE(heaps), SZ_1M,
- NvOsMemAttribute_WriteCombined));
- NV_CHECK_ERROR_CLEANUP(NvRmMemMap(s_KernelImage, 0, SZ_1M,
- NVOS_MEM_READ_WRITE, &map));
-
- phys = NvRmMemPin(s_KernelImage);
+ s_AvpClient = nvmap_create_client(nvmap_dev);
+ if (IS_ERR(s_AvpClient)) {
+ e = NvError_InsufficientMemory;
+ goto fail;
+ }
+
+ s_KernelImage = nvmap_alloc(s_AvpClient, SZ_1M, SZ_1M,
+ NVMAP_HANDLE_WRITE_COMBINE);
+ if (IS_ERR(s_KernelImage)) {
+ e = NvError_InsufficientMemory;
+ goto fail;
+ }
+
+ map = nvmap_mmap(s_KernelImage);
+ if (map == NULL) {
+ e = NvError_InsufficientMemory;
+ goto fail;
+ }
+
+ phys = nvmap_pin(s_AvpClient, s_KernelImage);
+ if (IS_ERR((void *)phys)) {
+ e = NvError_InsufficientMemory;
+ goto fail;
+ }
NV_CHECK_ERROR_CLEANUP(PrivateOsFopen("nvrm_avp.bin",
NVOS_OPEN_READ, &kernel));
- NvOsMemset(map, 0, SZ_1M);
+ memset(map, 0, SZ_1M);
len = (NvU32)kernel->pend - (NvU32)kernel->pstart;
- NvOsMemcpy(map, kernel->pstart, len);
+ memcpy(map, kernel->pstart, len);
+ wmb();
PrivateOsFclose(kernel);
@@ -591,7 +623,7 @@ static NvError NvRmPrivInitAvp(NvRmDeviceHandle hRm)
goto fail;
}
- NvRmMemUnmap(s_KernelImage, map, SZ_1M);
+ nvmap_munmap(s_KernelImage, map);
return NvSuccess;
@@ -599,11 +631,15 @@ fail:
writel(2 << 29, IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + FLOW_CTRL_HALT_COP);
if (map)
{
- NvRmMemUnpin(s_KernelImage);
- NvRmMemUnmap(s_KernelImage, map, SZ_1M);
+ if (!IS_ERR_OR_NULL((void *)phys))
+ nvmap_unpin(s_AvpClient, s_KernelImage);
}
- NvRmMemHandleFree(s_KernelImage);
+ if (!IS_ERR_OR_NULL(s_KernelImage))
+ nvmap_free(s_AvpClient, s_KernelImage);
+ if (!IS_ERR_OR_NULL(s_AvpClient))
+ nvmap_client_put(s_AvpClient);
s_KernelImage = NULL;
+ s_AvpClient = NULL;
return e;
}
@@ -712,31 +748,31 @@ int __init _avp_suspend_resume_init(void)
static int avp_suspend(struct platform_device *pdev, pm_message_t state)
{
- NvError err;
+ NvError err;
- err = NvRmPrivSuspendAvp(s_RPCHandle);
- if (err != NvSuccess)
- return -EIO;
- return 0;
+ err = NvRmPrivSuspendAvp(s_RPCHandle);
+ if (err != NvSuccess)
+ return -EIO;
+ return 0;
}
static int avp_resume(struct platform_device *pdev)
{
- NvError err;
+ NvError err;
- err = NvRmPrivResumeAvp(s_RPCHandle);
- if (err != NvSuccess)
- return -EIO;
- return 0;
+ err = NvRmPrivResumeAvp(s_RPCHandle);
+ if (err != NvSuccess)
+ return -EIO;
+ return 0;
}
static struct platform_driver avp_nvfw_driver = {
- .suspend = avp_suspend,
- .resume = avp_resume,
- .driver = {
- .name = "nvfw-avp-device",
- .owner = THIS_MODULE,
- },
+ .suspend = avp_suspend,
+ .resume = avp_resume,
+ .driver = {
+ .name = "nvfw-avp-device",
+ .owner = THIS_MODULE,
+ },
};
int __init _avp_suspend_resume_init(void);
diff --git a/arch/arm/mach-tegra/nv/nvrm/core/common/nvrm_transport.c b/arch/arm/mach-tegra/nv/nvrm/core/common/nvrm_transport.c
index 97a669879046..0ccd0784192e 100644
--- a/arch/arm/mach-tegra/nv/nvrm/core/common/nvrm_transport.c
+++ b/arch/arm/mach-tegra/nv/nvrm/core/common/nvrm_transport.c
@@ -39,6 +39,7 @@
* port exist in what processor (on same processor or other processor).
*/
+#include <linux/dma-mapping.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
@@ -238,16 +239,13 @@ typedef struct NvRmPrivPortsRec
// Mutex for transport
NvOsMutexHandle mutex;
-
- NvRmMemHandle hMessageMem;
- void *pTransmitMem;
- void *pReceiveMem;
- NvU32 MessageMemPhysAddr;
+ dma_addr_t messageDma;
+ void __iomem *pTransmitMem;
+ void __iomem *pReceiveMem;
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
+ // 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;
@@ -364,10 +362,6 @@ ExtractMessage(NvRmTransportHandle hPort, NvU8 *message, NvU32 *pMessageSize, Nv
hPort->RecvMessageQueue.ReadIndex = (NvU16)NextIndex;
}
-
-
-static void *s_TmpIsrMsgBuffer;
-
/**
* Connect message
* [ Transport Command ]
@@ -530,32 +524,12 @@ static void InboxFullIsr(void *args)
HandleAVPResetMessage(hDevice);
return;
}
- // if we're on the AVP, the first message we get will configure the message info
- if (s_TransportInfo.MessageMemPhysAddr == 0)
- {
- MessageData = MessageData;
- 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;
- }
+ BUG_ON(s_TransportInfo.pReceiveMem == NULL);
+ pMessage = (NvU32*)s_TransportInfo.pReceiveMem;
MessageCommand = pMessage[0];
@@ -613,76 +587,36 @@ RegisterTransportInterrupt(NvRmDeviceHandle hDevice)
void NvRmPrivXpcSendMsgAddress(void)
{
- BUG_ON(!s_TransportInfo.MessageMemPhysAddr);
+ BUG_ON(!s_TransportInfo.messageDma);
+ pr_info("msgBuff at %08x\n", s_TransportInfo.messageDma);
NvRmPrivXpcSendMessage(s_TransportInfo.hXpc,
- s_TransportInfo.MessageMemPhysAddr);
+ s_TransportInfo.messageDma);
}
+#define MESSAGE_DMA_SIZE (2 * (MAX_MESSAGE_LENGTH + MAX_COMMAND_SIZE))
+
// allocate buffers to be used for sending/receiving messages.
-static void
-NvRmPrivTransportAllocBuffers(NvRmDeviceHandle hRmDevice)
+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.pTransmitMem = dma_alloc_coherent(NULL, MESSAGE_DMA_SIZE,
+ &s_TransportInfo.messageDma, GFP_KERNEL);
- 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);
+ BUG_ON(!s_TransportInfo.pTransmitMem);
- return;
+ s_TransportInfo.pReceiveMem = s_TransportInfo.pTransmitMem +
+ MAX_MESSAGE_LENGTH + MAX_COMMAND_SIZE;
-
-fail:
- NvRmMemHandleFree(hNewMemHandle);
- s_TransportInfo.hMessageMem = NULL;
- return;
-#else
- return;
-#endif
+ // set this non-zero to throttle messages to the avp till avp is ready.
+ writel(0xdeadf00dul, s_TransportInfo.pTransmitMem);
+ writel(0, s_TransportInfo.pReceiveMem);
}
-static void
-NvRmPrivTransportFreeBuffers(NvRmDeviceHandle hRmDevice)
+static void NvRmPrivTransportFreeBuffers(NvRmDeviceHandle hRmDevice)
{
-#if !NV_IS_AVP
- NvRmMemHandleFree(s_TransportInfo.hMessageMem);
-#endif
+ dma_free_coherent(NULL, MESSAGE_DMA_SIZE, s_TransportInfo.pTransmitMem,
+ s_TransportInfo.messageDma);
}
static volatile NvBool s_Transport_Inited = NV_FALSE;
@@ -710,13 +644,6 @@ NvError NvRmTransportInit(NvRmDeviceHandle hRmDevice)
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;
@@ -746,7 +673,6 @@ fail:
NvRmPrivXpcDestroy(s_TransportInfo.hXpc);
NvRmPrivTransportFreeBuffers(hRmDevice);
#endif
- NvOsFree(s_TmpIsrMsgBuffer);
NvOsMutexDestroy(s_TransportInfo.mutex);
return err;
}
@@ -764,7 +690,6 @@ void NvRmTransportDeInit(NvRmDeviceHandle hRmDevice)
set_irq_flags(s_TransportInterruptHandle, IRQF_VALID);
s_TransportInterruptHandle = -1;
#endif
- NvOsFree(s_TmpIsrMsgBuffer);
NvOsMutexDestroy(s_TransportInfo.mutex);
}
@@ -1085,112 +1010,55 @@ exit_gracefully:
-static NvError
-NvRmPrivTransportWaitResponse(NvRmDeviceHandle hDevice, NvU32 *response, NvU32 ResponseLength, NvU32 TimeoutMS)
+static NvError NvRmPrivTransportWaitResponse(NvRmDeviceHandle hDevice,
+ NvU32 *response,
+ NvU32 ResponseLength,
+ NvU32 TimeoutMS)
{
- NvU32 CurrentTime;
+ NvU32 Elapsed;
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;
+ StartTime = NvOsGetTimeMS();
- // 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();
- }
- }
+ do {
+ Response = readl(s_TransportInfo.pTransmitMem);
+ if (Response == TransportCmd_Response)
+ break;
+ cpu_relax();
+ Elapsed = NvOsGetTimeMS() - StartTime;
+ } while (Elapsed < TimeoutMS);
- if ( pXpcMessage && GotResponse )
- {
- err = NvSuccess;
- NvOsMemcpy(response, (void *)pXpcMessage, ResponseLength);
- }
+ if (Response != TransportCmd_Response)
+ return NvError_Timeout;
- return err;
+ memcpy(response, s_TransportInfo.pTransmitMem, ResponseLength);
+ return NvSuccess;
}
static NvError NvRmPrivTransportSendMessage(NvRmDeviceHandle hDevice,
- NvU32 *MessageHdr, NvU32 MessageHdrLength,
- NvU32 *Message, NvU32 MessageLength)
+ NvU32 *MessageHdr,
+ NvU32 MessageHdrLength,
+ 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 = ((volatile NvU32*)s_TransportInfo.pTransmitMem)[0];
- }
+ BUG_ON(s_TransportInfo.pTransmitMem == NULL);
+ ReadData = readl(s_TransportInfo.pTransmitMem);
// Check for clear to send
- if ( ReadData != 0)
+ 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, MessageHdr, MessageHdrLength);
- if (Message && MessageLength)
- {
- NvRmMemWrite(s_TransportInfo.hMessageMem, MessageHdrLength,
- Message, MessageLength);
- }
- }
- else
+ memcpy(s_TransportInfo.pTransmitMem, MessageHdr, MessageHdrLength);
+ if (Message && MessageLength)
{
- NvOsMemcpy(s_TransportInfo.pTransmitMem, MessageHdr, MessageHdrLength);
- if (Message && MessageLength)
- {
- NvOsMemcpy(s_TransportInfo.pTransmitMem + MessageHdrLength,
- Message, MessageLength);
- }
- NvOsFlushWriteCombineBuffer();
+ memcpy(s_TransportInfo.pTransmitMem + MessageHdrLength,
+ Message, MessageLength);
}
- NvRmPrivXpcSendMessage(s_TransportInfo.hXpc, s_TransportInfo.MessageMemPhysAddr);
+ wmb();
+ NvRmPrivXpcSendMessage(s_TransportInfo.hXpc, s_TransportInfo.messageDma);
return NvSuccess;
}
@@ -1219,28 +1087,13 @@ NvError NvRmTransportSendMsgInLP0(NvRmTransportHandle hPort,
}
NvOsFlushWriteCombineBuffer();
- NvRmPrivXpcSendMessage(s_TransportInfo.hXpc, s_TransportInfo.MessageMemPhysAddr);
+ NvRmPrivXpcSendMessage(s_TransportInfo.hXpc, s_TransportInfo.messageDma);
return NvSuccess;
}
-static void
-NvRmPrivTransportClearSend(NvRmDeviceHandle hDevice)
+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;
- }
+ writel(TransportCmd_None, s_TransportInfo.pTransmitMem);
}
/**
@@ -1285,7 +1138,7 @@ NvError NvRmTransportConnect(NvRmTransportHandle hPort, NvU32 TimeoutMS)
break;
}
}
- else if (s_TransportInfo.hMessageMem || s_TransportInfo.pReceiveMem) // if no shared buffer, then we can't create a remote connection.
+ else if (s_TransportInfo.pReceiveMem)
{
ConnectMessage[0] = TransportCmd_Connect;
ConnectMessage[1] = (NvU32)hPort;
@@ -1573,8 +1426,6 @@ NvRmTransportRecvMsg(
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);
@@ -1605,23 +1456,8 @@ NvRmTransportRecvMsg(
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);
- }
+ BUG_ON(s_TransportInfo.pReceiveMem == NULL);
+ HandlePortMessage(hPort->hRmDevice, (NvU32*)s_TransportInfo.pReceiveMem);
}
#if LOOPBACK_PROFILE
diff --git a/arch/arm/mach-tegra/nv/nvrm_user.c b/arch/arm/mach-tegra/nv/nvrm_user.c
index 7357f61654c5..7bdfd01e7149 100644
--- a/arch/arm/mach-tegra/nv/nvrm_user.c
+++ b/arch/arm/mach-tegra/nv/nvrm_user.c
@@ -166,9 +166,10 @@ static void client_detach(NvRtClientHandle client)
void* ptr = NvRtFreeObjRef(&dctx,
NvRtObjType_NvRm_NvRmMemHandle,
NULL);
- if (!ptr) break;
+ WARN_ON_ONCE(ptr);
+ if (!ptr)
+ break;
NVRT_LEAK("NvRm", "NvRmMemHandle", ptr);
- NvRmMemHandleFree(ptr);
}
NvRtUnregisterClient(s_RtHandle, client);