mxc: gpu_viv: Don't try to Idle GPU after event submission

This code is attempting to IDLE the gpu after an event is
submitted, however this is generally followed by an interrupt
at the end of which the code attempts to idle the GPU.  This
generally causes Mutex contention with both threads trying
to do the same thing, set the powerstate to IDLE, or SUSPEND
depending on the driver preferences.
mxc: gpu_viv: Don't do an identity check for every commit

Everytime the GPU is woken up to process something an Identity
check is done to verify the GPU is present and active.  This is
really heavy handed and definitely causes excessive latency in
the kernel driver that is not needed.

FIXME: Find a better way to verify the GPU is ready to process
commands.
mxc: gpu_viv: Optimize PM routine

We are trying to manage multiple threads and a time trying to
put the GPU in the proper powerstate.  It is possible that while
the hardware is trying to power on the GPU the idle timer will
kick off and first suspend the chip only to wake it back up. This
commit does two things

1)  If the chip is already in the state we are trying to achieve
bail out and do nothing.
2)  If we are powering the chip on or off kill the IDLE timer
right away as we know we don't care about the suspend state because
we are already processing a different state command that is not
suspend.
GALCORE: fix race in _GetEvent()

Two _GetEvent()s can race, as it finds an event with a NULL head, and
then drops the lock:

Thread 0                        Thread 1
Calls _GetEvent
                                Calls _GetEvent
Acquires mutexQueue
Searches for a free entry
 by way of NULL queues[n].head
Finds entry N
Sets the stamp and source
Drops mutexQueue lock
returns event id N
                                Acquires MutexQueue
                                Searches for a free entry
                                 by way of NULL queues[n].head
                                Finds entry N
                                Sets the stamp and source
                                Drops mutexQueue lock
                                returns event id N
Sets the Event->queues[N].head
                                Sets Event->queues[N].head

This allows another thread to come in and also pick the same event.
Plug this race by holding the list lock over the call to _GetEvent,
and assign the head within _GetEvent().

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

Adapted to the V4 codebase

Signed-off-by: Jon Nettleton <jon.nettleton@gmail.com>
GALCORE: fix race in gckEvent_Notify()

This function can race with the setup of a new event queue.

Thread 0                        Thread 1
                                write Event->queues[i].head
read Event->queues[i].head
read Event->queues[i].stamp
                                write Event->queues[i].stamp
                                  with current stamp

Here, thread 0 has read a non-NULL head, but a old value for the stamp.
This leads gckEvent_Notify() to believe that this is an old event which
was not signalled by the GPU.  With some of the errors enabled, galcore
will issue a warning: Event N lost (stamp X)

More worrying is that it will immediately execute the attached event
list, and mark this event as completed - even though it's still being
setup.  This can result in problems such as GPU stalls being completed
early and command buffers being marked as completed (and hence re-used)
while the GPU is still reading commands from them.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

Adapted to the V4 codebase

Signed-off-by: Jon Nettleton <jon.nettleton@gmail.com>
GALCORE: fix race in _IsEmpty()

The following race is possible:

Thread 0                        Thread 1
Read Event->queues[0].head
Finds that it's NULL
                                Acquires Event->mutexQueue
                                Sets Event->queues[0].head
                                Releases Event->mutexQueue
Acquires Event->mutexQueue
Releases Event->mutexQueue
IsEmpty = True

Therefore, it is possible that this function returns with IsEmpty=TRUE
even though the event queues may not be empty.  The converse is also
possible:

Thread 0                        Thread 1 (event thread)
Read Event->queues[0].head
Finds that it's non-NULL
                                Receives interrupt
                                Acquires Event->mutexQueue
                                Clears Event->queues[0].head
                                Releases Event->mutexQueue
Acquires Event->mutexQueue
Releases Event->mutexQueue
IsEmpty = False

Here, the queues are empty, but we've returned that they not empty.

Fix this by reading the Event queue pointers beneath the lock.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

Adapted to the V4 codebase

Signed-off-by: Jon Nettleton <jon.nettleton@gmail.com>
GALCORE: fix LINK fetch size

The size of the destination command buffer was being padded to 64
bytes, whereas only 64 bits is required (as is the case for every
other LINK command.)  Make this consistent.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

Updated to the V4 codebase

Signed-off-by: Jon Nettleton <jon.nettleton@gmail.com>
mxc: gpu_viv: Fixup interrupt initialization

There is no reason to tear down and setup the interrupt constantly.
This breaks the routines up to  Setup/Remove and Enable/Disable,
it also consolidates the code to take Core as a parameter so
there aren't similar functions for the various Core types.
mxc: gpu_viv: Start with interrupts disabled.

Make sure interrupts are disabled so we don't get an unbalanced
irq later on.
mxc: gpu_viv: Wrap interrupt handling in a spinlock

Make sure that multiple threads are enabling/disabling irq's
when we are trying to read events pending.
mxc: gpu_viv: Disable VG for now

Build is broken so turn it off.  I don't need it.  Will debug
later.
GALCORE: refcount interrupt handling to prevent shutdown race

This fixes the following scenario.  First thread comes in with
a command queue, it takes the powersave mutex and then enables
interrupts if they are disabled, submits the command queue and
releases the powersave mutex.  Then the program doing the drawing
exits and releases the driver, which takes the powersave mutex
and issues a powerdown which disables irqs.  This can cause
an interrupts pending softirq crash.  Therefore we refcount all
the calls to enable interrupts and don't disable them until we are
back down to 0.
mxc: gpu_viv: Fix the include path for the sync header

In new upstream kernels the sync header is still in staging
for now just hard code the path.