GPIO performance ?

I am starting some experiments aimed at duplicating PC parallel port
interfacing on the BB.
I put together a little test program to toggle a GPIO pin, and was a
bit surprised at the low speed I was getting. I use mmap to set up
direct mapping to the GPIO, and then have code like this :
      gpio[0x8094/4] = 0x00000100; // set bit 8
      gpio[0x8090/4] = 0x00000100; // clear bit 8
      gpio[0x8094/4] = 0x00000100; // set bit 8
      gpio[0x8090/4] = 0x00000100; // clear bit 8
to toggle the bit. (These addresses map alternately to the set and
clear output bit registers)
I see the GPIO pin toggling every 250 ns, ie. high for 250 ns, low for
250 ns. Given the speed of
the OMAP3530, I would have expected this to happen much faster. Even
25 ns would have been no
concern. This 250 ns period is 150 CPU clock cycles.

Is there some kind of throttling on the GPIO? Can I reduce that
throttling without causing any other problems, such as with USB, SD
card, etc? I did see in the docs there is a clock for the GPIO, it
appeared to be global for the entire GPIO system. I can't figure out
what this clock rate is by default.

I am using a Debian 2.6.29-omap1 kernel with GCC 4.3.3

Thanks,

Jon

Hi !!
According my understanding , the GPIO module of OMAP use 32.768K clock
source.
That limit should answer your problem.

Claud Yu

Yes, I saw that, but it doesn't make sense. I can flip a GPIO pin
every 250 ns, with a ROCK-SOLID timing. So, it looks like maybe the
GPIO has been set to a 4 MHz clock. That I might be willing to
believe. Is there a way to change the clock, and will it interfere
with anything else, like the USB or SD card? Turning the clock up
might use more power, but this is not a mobile, battery-powered
application, so we aren't really worried about a small power
increase. Going up to a 10 or 20 MHz clock would probably be fine for
this project.

If the GPIO is on a 4 MHz clock, there must be some interlocking to
keep the CPU from running ahead of the GPIO.

Thanks,

Jon

First of all, you're not going to be guaranteed that that process
you're executing (to toggle GPIO bits) will run at every given moment
- each thread has a scheduling quantum that will eventually be
relinquished to other processes by the Linux scheduler - hence, for
any fine grained GPIO toggling with deterministic behaviour (all the
time), this might not be the best approach.

And yes, the clocking to the GPIO module is determined by the PRCM
module (power, reset, clock management module) - its best to check
there to see which of the multiple clocks it generates ends up going
to the GPIO peripheral. I believe the 2.6.29 and greater kernels have
support for this built-in.

Jerry

First of all, you're not going to be guaranteed that that process
you're executing (to toggle GPIO bits) will run at every given moment
- each thread has a scheduling quantum that will eventually be
relinquished to other processes by the Linux scheduler - hence, for
any fine grained GPIO toggling with deterministic behaviour (all the
time), this might not be the best approach.

The real application will run under a real-time patched Linux kernel,
hopefully
with rtai. Precise timing is not the point here, just good
througput. Right now it appears
that the GPIO clock is by default set to 4 MHz, limiting everything to
250 ns alignment.
This is marginally OK for what we want to do, but if it were possible
to turn up that clock
a couple powers of two, it would be ideal.

Right now I am trying to get some handle on the basic control of GPIO
pins, then I will
build a voltage level translator/interface board to hook to the
expansion header.
Then I will try writing a user-level "driver" to debug the basic
sequence of operations
before trying to make any of it work in the real-time environment.

And yes, the clocking to the GPIO module is determined by the PRCM
module (power, reset, clock management module) - its best to check
there to see which of the multiple clocks it generates ends up going
to the GPIO peripheral. I believe the 2.6.29 and greater kernels have
support for this built-in.

Oh, excellent, having kernel support would be much better than writing
to hardware
registers with such wide-ranging implications. Is there any place
where the kernel
calls for this are documented?

I've been reading the ref manual on the PRCM, it is VERY verbose and
hard to follow.

Thanks a lot, I much appreciate the info.

Jon