// ----------------------------------------------------------------------
//
// OMAP3530 DSP MMU utility functions.
// copyright and written by Nils Pipenbrinck 2010
//
// This code is released under the BSD license.
//
// ----------------------------------------------------------------------
//
// 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 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
// OWNER 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 <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <sys/mman.h>
#include <proc.h>
#include "dsp_mmu_util.h"
// only required for the CMEM related functions.
#include "cmem.h"
int dsp_mmu_map (unsigned long physical_ptr, int size)
///////////////////////////////////////////////////////////
// Maps a physical memory region into the DSP address-space
{
ProcMemMapInfo mapInfo;
mapInfo.dspAddr = (Uint32)physical_ptr;
mapInfo.size = size;
return DSP_SUCCEEDED(PROC_control(0, PROC_CTRL_CMD_MMU_ADD_ENTRY, &mapInfo));
}
int dsp_mmu_unmap (unsigned long dspAddr, int size)
///////////////////////////////////////////////////////////
// Unmaps a physical memory region into the DSP address-space
{
ProcMemMapInfo mapInfo;
mapInfo.dspAddr = (Uint32)dspAddr;
mapInfo.size = size;
return DSP_SUCCEEDED(PROC_control(0, PROC_CTRL_CMD_MMU_DEL_ENTRY, &mapInfo));
}
int dsp_mmu_map_cmem (void)
/////////////////////////////////////////
// map first cmem block into the DSP MMU:
{
CMEM_BlockAttrs info;
if (CMEM_getBlockAttrs(0, &info) != 0)
return 0;
return dsp_mmu_map (info.phys_base, info.size);
}
int dsp_mmu_unmap_cmem (void)
//////////////////////////////////////////
// umap first cmem block into the DSP MMU:
{
CMEM_BlockAttrs info;
if (CMEM_getBlockAttrs(0, &info) != 0)
return 0;
return dsp_mmu_unmap (info.phys_base, info.size);
}
int dsp_mmu_disable (void)
//////////////////////////
// Disables the DSP MMU.
// Sets virtual = physical mapping.
{
volatile unsigned long * mmu;
int result = 0;
// physical addres of the MMU2 and some register offsets:
const unsigned MMU2_PHYSICAL = 0x5d000000;
const unsigned MMU_SYSCONFIG = 4;
const unsigned MMU_SYSSTATUS = 5;
const unsigned MMU_CNTL = 17;
int fd = open("/dev/mem", O_RDWR);
if (fd>=0)
{
// get a pointer to the MMU2 register space:
mmu = (unsigned long *) mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, MMU2_PHYSICAL);
if (mmu != MAP_FAILED)
{
int result = 1;
time_t start;
// A timeout of 10 milliseconds is more then plenty.
//
// Usually the reset takes about 10 microseconds.
// It never happend to me that the reset didn't
// succeded, but better safe than sorry.
time_t timeout = (CLOCKS_PER_SEC/100);
// start MMU soft-reset:
mmu[MMU_SYSCONFIG] |= 1;
// wait (with timeout) until the reset is complete.
start = clock();
while ((!mmu[MMU_SYSSTATUS]) && (clock()-start < timeout)) {}
if (mmu[MMU_SYSSTATUS])
{
// disable MMU
mmu[MMU_CNTL] =0;
// set result to SUCCESS.
result = 1;
}
// remove mapping:
munmap((void*)mmu, 4096);
}
close (fd);
}
// failed:
return result;
}
评论0