diff options
author | Gary King <gking@nvidia.com> | 2010-09-09 17:04:17 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2010-10-19 13:35:02 -0700 |
commit | da33d5cff9a52787290e2cabf0da2cc7ab9dba5a (patch) | |
tree | e1a3e6f180cfb1d26b9f77e2f216f69b289cd821 /arch/arm/mach-tegra/nv | |
parent | 760138ecbcbeb79d5618075a460352a32f8f65aa (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.c | 162 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nv/nvrm/core/common/nvrm_moduleloader.c | 128 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nv/nvrm/core/common/nvrm_transport.c | 282 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nv/nvrm_user.c | 5 |
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); |