Question

Disclaimer: I am kind of cross-posting this question on the Texas Instruments Forum, but I haven't gotten any response there for five days. I am pretty new to embedded programming, so please point out if you need additional information or if my approach is nonsensical.

Motivation

I have an embedded device with a DM3730 processor from Texas Instruments (The same you find on the Beagleboard -xm) The processor is connected to an LCD Display through its Display Subsystem (DSS). The display seems very dark and has to be gamma corrected. Fortunately, the DSS has a Palette/gamma lookup-table. Unfortunately, I am unable to get it to work.

What I found out

I found a similar question on the Texas Instruments Forum for a comparable processor and a TI employee gave the following explanation (emphasis mine):

I don't think there is any support in the current Linux kernel for color indexed graphics, but it is fairly easy to enable from the application level through direct register configuration.

[...]

Next, declare an array of 256 unsigned integers and populate it with the RGB values you want for each color index entry.

Set DISPC_GFX_TABLE_BA to the physical address of the previously configured array (Note 1, this needs the physical address and not the virtual address so you will likely need to map it back. Note 2, this needs to be a 32 bit aligned address so depending on how the array is created it may be necessary to create an array of char slightly larger and populate the array such that the start is on a 32 bit boundary)

[...]

He later refers to the mem_util to translate addresses and I was able to use this to write directly to registers from the application level (user space), but I cannot figure out how to "map back" a virtual address to a physical address.

System Information

~# uname -a
Linux dm37x-evm 2.6.32.1 #1 Fri Dec 2 11:19:53 EST 2011 armv7l unknown

My Questions

  • How do I map a virtual address back to a physical address?
  • Can this be done in user space? (I am envisioning that I provide an interface where the user can adjust the gamma curve)
  • Is this the right approach in general? Should I move this to kernel space (I am reluctant to do this since I don't have a lot of experience with the Linux Kernel)
  • Any good resources or examples!
Was it helpful?

Solution

A very specific answer to your problem, is to use CMEM, which purpose is to allocate contiuguous chunk of memory from boot time reserved memory.

In the example code below, I use cmem through the codec engine. ptr is what you use in your application to access the buffer, while physptr is what you write in the registers.

    ptr = Memory_contigAlloc(len, Memory_DEFAULTALIGNMENT);
    if(ptr == NULL) {
        debug_printf("Buffer allocation failed : buf size = %d\n", len);
        return -1;
    }
    physptr = (void *)Memory_getBufferPhysicalAddress(ptr, len, 0);

The "right" approach is effectively not to use memutil and do the whole thing in kernel.

OTHER TIPS

There is a CMEM driver, which is used for mapping physical memory to user-space memory. It can do virtual-to-physical translation too.

So, with this driver you can:

  1. Allocate aligned buffer
  2. Get user-space address
  3. Fill the buffer from your program
  4. Get physical address of the buffer
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top