Patchwork [meta-fsl-arm-extra,2/2] linux-boundary: Add support to Vivante 4.6.9p12 GPU code

login
register
mail settings
Submitter Otavio Salvador
Date July 23, 2013, 6:59 p.m.
Message ID <1374605958-21049-2-git-send-email-otavio@ossystems.com.br>
Download mbox | patch
Permalink /patch/54255/
State Superseded
Delegated to: Otavio Salvador
Headers show

Comments

Otavio Salvador - July 23, 2013, 6:59 p.m.
This backport the support for Vivante 4.6.9p12 GPU from 3.5.7 kernel
while Freescale does not make a new 3.0.35 release with this.

Change-Id: If3bf361344d6a661a141e5545d5ab381865b10e6
Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
---
 ...8-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch | 1040 ++++++++++
 ...5-gpu-Add-global-value-for-minimum-3D-clo.patch |   62 +
 ...4-4-gpu-use-new-PU-power-on-off-interface.patch |   53 +
 ...8-1-GPU-Integrate-4.6.9p12-release-kernel.patch | 2006 ++++++++++++++++++++
 ...5-GPU-Correct-suspend-resume-calling-afte.patch |   61 +
 ...0-gpu-Correct-section-mismatch-in-gpu-ker.patch |   60 +
 recipes-kernel/linux/linux-boundary_3.0.35.bb      |   10 +-
 7 files changed, 3291 insertions(+), 1 deletion(-)
 create mode 100644 recipes-kernel/linux/linux-boundary-3.0.35/0001-ENGR00255688-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch
 create mode 100644 recipes-kernel/linux/linux-boundary-3.0.35/0002-ENGR00265465-gpu-Add-global-value-for-minimum-3D-clo.patch
 create mode 100644 recipes-kernel/linux/linux-boundary-3.0.35/0003-ENGR00261814-4-gpu-use-new-PU-power-on-off-interface.patch
 create mode 100644 recipes-kernel/linux/linux-boundary-3.0.35/0004-ENGR00264288-1-GPU-Integrate-4.6.9p12-release-kernel.patch
 create mode 100644 recipes-kernel/linux/linux-boundary-3.0.35/0005-ENGR00264275-GPU-Correct-suspend-resume-calling-afte.patch
 create mode 100644 recipes-kernel/linux/linux-boundary-3.0.35/0006-ENGR00265130-gpu-Correct-section-mismatch-in-gpu-ker.patch
Eric Nelson - Aug. 10, 2013, 6:10 p.m.
Thanks Otavio.

On 07/23/2013 11:59 AM, Otavio Salvador wrote:
> This backport the support for Vivante 4.6.9p12 GPU from 3.5.7 kernel
> while Freescale does not make a new 3.0.35 release with this.
>
> Change-Id: If3bf361344d6a661a141e5545d5ab381865b10e6
> Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
> ---
>   ...8-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch | 1040 ++++++++++
>   ...5-gpu-Add-global-value-for-minimum-3D-clo.patch |   62 +
>   ...4-4-gpu-use-new-PU-power-on-off-interface.patch |   53 +
>   ...8-1-GPU-Integrate-4.6.9p12-release-kernel.patch | 2006 ++++++++++++++++++++
>   ...5-GPU-Correct-suspend-resume-calling-afte.patch |   61 +
>   ...0-gpu-Correct-section-mismatch-in-gpu-ker.patch |   60 +
>   recipes-kernel/linux/linux-boundary_3.0.35.bb      |   10 +-
>   7 files changed, 3291 insertions(+), 1 deletion(-)
>   create mode 100644 recipes-kernel/linux/linux-boundary-3.0.35/0001-ENGR00255688-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch
>   create mode 100644 recipes-kernel/linux/linux-boundary-3.0.35/0002-ENGR00265465-gpu-Add-global-value-for-minimum-3D-clo.patch
>   create mode 100644 recipes-kernel/linux/linux-boundary-3.0.35/0003-ENGR00261814-4-gpu-use-new-PU-power-on-off-interface.patch
>   create mode 100644 recipes-kernel/linux/linux-boundary-3.0.35/0004-ENGR00264288-1-GPU-Integrate-4.6.9p12-release-kernel.patch
>   create mode 100644 recipes-kernel/linux/linux-boundary-3.0.35/0005-ENGR00264275-GPU-Correct-suspend-resume-calling-afte.patch
>   create mode 100644 recipes-kernel/linux/linux-boundary-3.0.35/0006-ENGR00265130-gpu-Correct-section-mismatch-in-gpu-ker.patch
>

Aren't these easier to carry in our kernel repository?

If so, I applied them to a branch with a hideously long name:
	boundary-imx_3.0.35_4.0.0-plus-vivante-4.6.9p11.1

https://github.com/boundarydevices/linux-imx6/tree/boundary-imx_3.0.35_4.0.0-plus-vivante-4.6.9p11.1

Does anybody know if there are ABI changes in the corresponding
userspace bits?

How about release notes?

Please advise,


Eric
Otavio Salvador - Aug. 10, 2013, 7:25 p.m.
On Sat, Aug 10, 2013 at 3:10 PM, Eric Nelson
<eric.nelson@boundarydevices.com> wrote:
> Thanks Otavio.
>
>
> On 07/23/2013 11:59 AM, Otavio Salvador wrote:
>>
>> This backport the support for Vivante 4.6.9p12 GPU from 3.5.7 kernel
>> while Freescale does not make a new 3.0.35 release with this.
>>
>> Change-Id: If3bf361344d6a661a141e5545d5ab381865b10e6
>> Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
>> ---
>>   ...8-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch | 1040 ++++++++++
>>   ...5-gpu-Add-global-value-for-minimum-3D-clo.patch |   62 +
>>   ...4-4-gpu-use-new-PU-power-on-off-interface.patch |   53 +
>>   ...8-1-GPU-Integrate-4.6.9p12-release-kernel.patch | 2006
>> ++++++++++++++++++++
>>   ...5-GPU-Correct-suspend-resume-calling-afte.patch |   61 +
>>   ...0-gpu-Correct-section-mismatch-in-gpu-ker.patch |   60 +
>>   recipes-kernel/linux/linux-boundary_3.0.35.bb      |   10 +-
>>   7 files changed, 3291 insertions(+), 1 deletion(-)
>>   create mode 100644
>> recipes-kernel/linux/linux-boundary-3.0.35/0001-ENGR00255688-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch
>>   create mode 100644
>> recipes-kernel/linux/linux-boundary-3.0.35/0002-ENGR00265465-gpu-Add-global-value-for-minimum-3D-clo.patch
>>   create mode 100644
>> recipes-kernel/linux/linux-boundary-3.0.35/0003-ENGR00261814-4-gpu-use-new-PU-power-on-off-interface.patch
>>   create mode 100644
>> recipes-kernel/linux/linux-boundary-3.0.35/0004-ENGR00264288-1-GPU-Integrate-4.6.9p12-release-kernel.patch
>>   create mode 100644
>> recipes-kernel/linux/linux-boundary-3.0.35/0005-ENGR00264275-GPU-Correct-suspend-resume-calling-afte.patch
>>   create mode 100644
>> recipes-kernel/linux/linux-boundary-3.0.35/0006-ENGR00265130-gpu-Correct-section-mismatch-in-gpu-ker.patch
>>
>
> Aren't these easier to carry in our kernel repository?

It can be done. I did the same change in all kernel I could so it'd be
made compatible with the new GPU binary.

> If so, I applied them to a branch with a hideously long name:
>         boundary-imx_3.0.35_4.0.0-plus-vivante-4.6.9p11.1
>
> https://github.com/boundarydevices/linux-imx6/tree/boundary-imx_3.0.35_4.0.0-plus-vivante-4.6.9p11.1

In fact it is p12 version.

> Does anybody know if there are ABI changes in the corresponding
> userspace bits?

It has.

> How about release notes?

Daiane, do you know where is 3.5.7 release notes?
Eric Nelson - Aug. 10, 2013, 10:12 p.m.
Thanks again, Otavio.

On 08/10/2013 12:25 PM, Otavio Salvador wrote:
> On Sat, Aug 10, 2013 at 3:10 PM, Eric Nelson
> <eric.nelson@boundarydevices.com> wrote:
>> Thanks Otavio.
>>
>>
>> On 07/23/2013 11:59 AM, Otavio Salvador wrote:
>>>
>>> This backport the support for Vivante 4.6.9p12 GPU from 3.5.7 kernel
>>> while Freescale does not make a new 3.0.35 release with this.
>>>
>>> Change-Id: If3bf361344d6a661a141e5545d5ab381865b10e6
>>> Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
>>> ---
>>>    ...8-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch | 1040 ++++++++++
>>>    ...5-gpu-Add-global-value-for-minimum-3D-clo.patch |   62 +
>>>    ...4-4-gpu-use-new-PU-power-on-off-interface.patch |   53 +
>>>    ...8-1-GPU-Integrate-4.6.9p12-release-kernel.patch | 2006
>>> ++++++++++++++++++++
>>>    ...5-GPU-Correct-suspend-resume-calling-afte.patch |   61 +
>>>    ...0-gpu-Correct-section-mismatch-in-gpu-ker.patch |   60 +
>>>    recipes-kernel/linux/linux-boundary_3.0.35.bb      |   10 +-
>>>    7 files changed, 3291 insertions(+), 1 deletion(-)
>>>    create mode 100644
>>> recipes-kernel/linux/linux-boundary-3.0.35/0001-ENGR00255688-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch
>>>    create mode 100644
>>> recipes-kernel/linux/linux-boundary-3.0.35/0002-ENGR00265465-gpu-Add-global-value-for-minimum-3D-clo.patch
>>>    create mode 100644
>>> recipes-kernel/linux/linux-boundary-3.0.35/0003-ENGR00261814-4-gpu-use-new-PU-power-on-off-interface.patch
>>>    create mode 100644
>>> recipes-kernel/linux/linux-boundary-3.0.35/0004-ENGR00264288-1-GPU-Integrate-4.6.9p12-release-kernel.patch
>>>    create mode 100644
>>> recipes-kernel/linux/linux-boundary-3.0.35/0005-ENGR00264275-GPU-Correct-suspend-resume-calling-afte.patch
>>>    create mode 100644
>>> recipes-kernel/linux/linux-boundary-3.0.35/0006-ENGR00265130-gpu-Correct-section-mismatch-in-gpu-ker.patch
>>>
>>
>> Aren't these easier to carry in our kernel repository?
>
> It can be done. I did the same change in all kernel I could so it'd be
> made compatible with the new GPU binary.
>
>> If so, I applied them to a branch with a hideously long name:
>>          boundary-imx_3.0.35_4.0.0-plus-vivante-4.6.9p11.1
>>
>> https://github.com/boundarydevices/linux-imx6/tree/boundary-imx_3.0.35_4.0.0-plus-vivante-4.6.9p11.1
>
> In fact it is p12 version.
>
Oops. I grabbed this from the first patch file in the series.
I renamed the branch in case it's helpful:
	 boundary-imx_3.0.35_4.0.0-plus-vivante-4.6.9p11.1

>> Does anybody know if there are ABI changes in the corresponding
>> userspace bits?
>
> It has.
>

If so, then we'll want them segregated into separate branches or the
patch files conditionally applied, right?

Right now, gpu-viv-bin-mx6q-3.5.7-1.0.0-hfp.bin only supports hard
float. Will the EABI (4.0.0) binaries continue to be supported or
will there be a corresponding package of EABI binaries?
Otavio Salvador - Aug. 12, 2013, 12:50 p.m.
On Sat, Aug 10, 2013 at 7:12 PM, Eric Nelson
<eric.nelson@boundarydevices.com> wrote:
> On 08/10/2013 12:25 PM, Otavio Salvador wrote:
>> On Sat, Aug 10, 2013 at 3:10 PM, Eric Nelson
> Oops. I grabbed this from the first patch file in the series.
> I renamed the branch in case it's helpful:
>          boundary-imx_3.0.35_4.0.0-plus-vivante-4.6.9p11.1

Fine. Thanks.

>>> Does anybody know if there are ABI changes in the corresponding
>>> userspace bits?
>>
>>
>> It has.
>>
>
> If so, then we'll want them segregated into separate branches or the
> patch files conditionally applied, right?
>
> Right now, gpu-viv-bin-mx6q-3.5.7-1.0.0-hfp.bin only supports hard
> float. Will the EABI (4.0.0) binaries continue to be supported or
> will there be a corresponding package of EABI binaries?

There's also a gpu-viv-bin-mx6q-3.5.7-1.0.0-sfp.bin and it is taken in
case you're building for Soft Float-Point. It should 'Just Work'.

So far, all worked fine for me. Can you give it a try?
Daiane Angolini - Aug. 12, 2013, 1:02 p.m.
On 08/10/2013 04:25 PM, Otavio Salvador wrote:
> On Sat, Aug 10, 2013 at 3:10 PM, Eric Nelson
> <eric.nelson@boundarydevices.com> wrote:
>> Thanks Otavio.
>>
>>
>> On 07/23/2013 11:59 AM, Otavio Salvador wrote:
>>>
>>> This backport the support for Vivante 4.6.9p12 GPU from 3.5.7 kernel
>>> while Freescale does not make a new 3.0.35 release with this.
>>>
>>> Change-Id: If3bf361344d6a661a141e5545d5ab381865b10e6
>>> Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
>>> ---
>>>    ...8-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch | 1040 ++++++++++
>>>    ...5-gpu-Add-global-value-for-minimum-3D-clo.patch |   62 +
>>>    ...4-4-gpu-use-new-PU-power-on-off-interface.patch |   53 +
>>>    ...8-1-GPU-Integrate-4.6.9p12-release-kernel.patch | 2006
>>> ++++++++++++++++++++
>>>    ...5-GPU-Correct-suspend-resume-calling-afte.patch |   61 +
>>>    ...0-gpu-Correct-section-mismatch-in-gpu-ker.patch |   60 +
>>>    recipes-kernel/linux/linux-boundary_3.0.35.bb      |   10 +-
>>>    7 files changed, 3291 insertions(+), 1 deletion(-)
>>>    create mode 100644
>>> recipes-kernel/linux/linux-boundary-3.0.35/0001-ENGR00255688-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch
>>>    create mode 100644
>>> recipes-kernel/linux/linux-boundary-3.0.35/0002-ENGR00265465-gpu-Add-global-value-for-minimum-3D-clo.patch
>>>    create mode 100644
>>> recipes-kernel/linux/linux-boundary-3.0.35/0003-ENGR00261814-4-gpu-use-new-PU-power-on-off-interface.patch
>>>    create mode 100644
>>> recipes-kernel/linux/linux-boundary-3.0.35/0004-ENGR00264288-1-GPU-Integrate-4.6.9p12-release-kernel.patch
>>>    create mode 100644
>>> recipes-kernel/linux/linux-boundary-3.0.35/0005-ENGR00264275-GPU-Correct-suspend-resume-calling-afte.patch
>>>    create mode 100644
>>> recipes-kernel/linux/linux-boundary-3.0.35/0006-ENGR00265130-gpu-Correct-section-mismatch-in-gpu-ker.patch
>>>
>>
>> Aren't these easier to carry in our kernel repository?
>
> It can be done. I did the same change in all kernel I could so it'd be
> made compatible with the new GPU binary.
>
>> If so, I applied them to a branch with a hideously long name:
>>          boundary-imx_3.0.35_4.0.0-plus-vivante-4.6.9p11.1
>>
>> https://github.com/boundarydevices/linux-imx6/tree/boundary-imx_3.0.35_4.0.0-plus-vivante-4.6.9p11.1
>
> In fact it is p12 version.
>
>> Does anybody know if there are ABI changes in the corresponding
>> userspace bits?
>
> It has.
>
>> How about release notes?
>
> Daiane, do you know where is 3.5.7 release notes?
>

I don't have the link right now, but as I know it's on a compass shared 
only with customers that has access to alpha releases.
Eric Nelson - Aug. 12, 2013, 2:05 p.m.
Thanks Otavio,

On 08/12/2013 05:50 AM, Otavio Salvador wrote:
> On Sat, Aug 10, 2013 at 7:12 PM, Eric Nelson
> <eric.nelson@boundarydevices.com> wrote:
>> On 08/10/2013 12:25 PM, Otavio Salvador wrote:
>>> On Sat, Aug 10, 2013 at 3:10 PM, Eric Nelson
>> Oops. I grabbed this from the first patch file in the series.
>> I renamed the branch in case it's helpful:
>>           boundary-imx_3.0.35_4.0.0-plus-vivante-4.6.9p11.1
>
> Fine. Thanks.
>
>>>> Does anybody know if there are ABI changes in the corresponding
>>>> userspace bits?
>>>
>>>
>>> It has.
>>>
>>
>> If so, then we'll want them segregated into separate branches or the
>> patch files conditionally applied, right?
>>
>> Right now, gpu-viv-bin-mx6q-3.5.7-1.0.0-hfp.bin only supports hard
>> float. Will the EABI (4.0.0) binaries continue to be supported or
>> will there be a corresponding package of EABI binaries?
>
> There's also a gpu-viv-bin-mx6q-3.5.7-1.0.0-sfp.bin and it is taken in
> case you're building for Soft Float-Point. It should 'Just Work'.
>

If that's the case, we can just push the patches onto our
main branch and not deal with the old/new GPU package question.

> So far, all worked fine for me. Can you give it a try?
>

Absolutely. I'll give this a spin.
Otavio Salvador - Aug. 12, 2013, 3:18 p.m.
On Mon, Aug 12, 2013 at 11:05 AM, Eric Nelson
<eric.nelson@boundarydevices.com> wrote:
> On 08/12/2013 05:50 AM, Otavio Salvador wrote:
>> On Sat, Aug 10, 2013 at 7:12 PM, Eric Nelson
>> <eric.nelson@boundarydevices.com> wrote:
>>> Right now, gpu-viv-bin-mx6q-3.5.7-1.0.0-hfp.bin only supports hard
>>> float. Will the EABI (4.0.0) binaries continue to be supported or
>>> will there be a corresponding package of EABI binaries?
>>
>>
>> There's also a gpu-viv-bin-mx6q-3.5.7-1.0.0-sfp.bin and it is taken in
>> case you're building for Soft Float-Point. It should 'Just Work'.
>>
>
> If that's the case, we can just push the patches onto our
> main branch and not deal with the old/new GPU package question.

Not really as it will make impossible for your customers to use the
kernel with LTIB at 4.0.0 BSP (well, I'd love they stop using it
but...).
Eric Nelson - Aug. 12, 2013, 3:48 p.m.
On 08/12/2013 08:18 AM, Otavio Salvador wrote:
> On Mon, Aug 12, 2013 at 11:05 AM, Eric Nelson
> <eric.nelson@boundarydevices.com> wrote:
>> On 08/12/2013 05:50 AM, Otavio Salvador wrote:
>>> On Sat, Aug 10, 2013 at 7:12 PM, Eric Nelson
>>> <eric.nelson@boundarydevices.com> wrote:
>>>> Right now, gpu-viv-bin-mx6q-3.5.7-1.0.0-hfp.bin only supports hard
>>>> float. Will the EABI (4.0.0) binaries continue to be supported or
>>>> will there be a corresponding package of EABI binaries?
>>>
>>> There's also a gpu-viv-bin-mx6q-3.5.7-1.0.0-sfp.bin and it is taken in
>>> case you're building for Soft Float-Point. It should 'Just Work'.
>>>
>>
>> If that's the case, we can just push the patches onto our
>> main branch and not deal with the old/new GPU package question.
>
> Not really as it will make impossible for your customers to use the
> kernel with LTIB at 4.0.0 BSP (well, I'd love they stop using it
> but...).
>

It's not just LTIB that's a question mark. The same comment
goes for Debian, Buildroot, Timesys, Ubuntu, Arch or home-brew
userspaces.

If it's Freescale's recommendation that this GPU package is
the **right** one for production use, our primary kernel
branch should probably reflect that.

There's no reason someone using another userspace builder
can't patch their process to update things.

That said, I haven't quite heard this as Freescale's recommendation.
Daiane, I don't suppose you want to stick your neck out...?

Regards,


Eric
Otavio Salvador - Aug. 12, 2013, 4:34 p.m.
On Mon, Aug 12, 2013 at 12:48 PM, Eric Nelson
<eric.nelson@boundarydevices.com> wrote:
> On 08/12/2013 08:18 AM, Otavio Salvador wrote:
>>
>> On Mon, Aug 12, 2013 at 11:05 AM, Eric Nelson
>> <eric.nelson@boundarydevices.com> wrote:
>>>
>>> On 08/12/2013 05:50 AM, Otavio Salvador wrote:
>>>>
>>>> On Sat, Aug 10, 2013 at 7:12 PM, Eric Nelson
>>>> <eric.nelson@boundarydevices.com> wrote:
>>>>>
>>>>> Right now, gpu-viv-bin-mx6q-3.5.7-1.0.0-hfp.bin only supports hard
>>>>> float. Will the EABI (4.0.0) binaries continue to be supported or
>>>>> will there be a corresponding package of EABI binaries?
>>>>
>>>>
>>>> There's also a gpu-viv-bin-mx6q-3.5.7-1.0.0-sfp.bin and it is taken in
>>>> case you're building for Soft Float-Point. It should 'Just Work'.
>>>>
>>>
>>> If that's the case, we can just push the patches onto our
>>> main branch and not deal with the old/new GPU package question.
>>
>>
>> Not really as it will make impossible for your customers to use the
>> kernel with LTIB at 4.0.0 BSP (well, I'd love they stop using it
>> but...).
>>
>
> It's not just LTIB that's a question mark. The same comment
> goes for Debian, Buildroot, Timesys, Ubuntu, Arch or home-brew
> userspaces.
>
> If it's Freescale's recommendation that this GPU package is
> the **right** one for production use, our primary kernel
> branch should probably reflect that.

I think the recommendation is to stay in their 'official' and 'test'
set of packages so I think it is better to have p12 support as patches
so it is clear it is something we are doing 'by ourselves'.

> There's no reason someone using another userspace builder
> can't patch their process to update things.

Well yes but it makes their life harder and a branch which won't work
with 'official' package set. So I think patches are the way to go for
now.

> That said, I haven't quite heard this as Freescale's recommendation.
> Daiane, I don't suppose you want to stick your neck out...?

Poor Daiane ;-)
Daiane Angolini - Aug. 12, 2013, 4:45 p.m.
On 08/12/2013 01:34 PM, Otavio Salvador wrote:
> On Mon, Aug 12, 2013 at 12:48 PM, Eric Nelson
> <eric.nelson@boundarydevices.com> wrote:
>> On 08/12/2013 08:18 AM, Otavio Salvador wrote:
>>>
>>> On Mon, Aug 12, 2013 at 11:05 AM, Eric Nelson
>>> <eric.nelson@boundarydevices.com> wrote:
>>>>
>>>> On 08/12/2013 05:50 AM, Otavio Salvador wrote:
>>>>>
>>>>> On Sat, Aug 10, 2013 at 7:12 PM, Eric Nelson
>>>>> <eric.nelson@boundarydevices.com> wrote:
>>>>>>
>>>>>> Right now, gpu-viv-bin-mx6q-3.5.7-1.0.0-hfp.bin only supports hard
>>>>>> float. Will the EABI (4.0.0) binaries continue to be supported or
>>>>>> will there be a corresponding package of EABI binaries?
>>>>>
>>>>>
>>>>> There's also a gpu-viv-bin-mx6q-3.5.7-1.0.0-sfp.bin and it is taken in
>>>>> case you're building for Soft Float-Point. It should 'Just Work'.
>>>>>
>>>>
>>>> If that's the case, we can just push the patches onto our
>>>> main branch and not deal with the old/new GPU package question.
>>>
>>>
>>> Not really as it will make impossible for your customers to use the
>>> kernel with LTIB at 4.0.0 BSP (well, I'd love they stop using it
>>> but...).
>>>
>>
>> It's not just LTIB that's a question mark. The same comment
>> goes for Debian, Buildroot, Timesys, Ubuntu, Arch or home-brew
>> userspaces.
>>
>> If it's Freescale's recommendation that this GPU package is
>> the **right** one for production use, our primary kernel
>> branch should probably reflect that.
>
> I think the recommendation is to stay in their 'official' and 'test'
> set of packages so I think it is better to have p12 support as patches
> so it is clear it is something we are doing 'by ourselves'.

3.5.7-1.0.0 - is an alpha release. It does not have the same "stability" 
comparing with a GA release. It is not shared with *all* customers.

>
>> There's no reason someone using another userspace builder
>> can't patch their process to update things.
>
> Well yes but it makes their life harder and a branch which won't work
> with 'official' package set. So I think patches are the way to go for
> now.
>
>> That said, I haven't quite heard this as Freescale's recommendation.
>> Daiane, I don't suppose you want to stick your neck out...?
>
> Poor Daiane ;-)

When I'm talking to meta-freescale I'm "Freescale". When I'm talking to 
guys inside Freescale, I'm "community".

Here, I can only say public and official stuff. If you need Freescale's 
help, please enter a SR or a question on imx-community.

=(
Eric Nelson - Aug. 12, 2013, 5:07 p.m.
On 08/12/2013 09:45 AM, Daiane Angolini wrote:
> On 08/12/2013 01:34 PM, Otavio Salvador wrote:
>> On Mon, Aug 12, 2013 at 12:48 PM, Eric Nelson
>> <eric.nelson@boundarydevices.com> wrote:
>>> On 08/12/2013 08:18 AM, Otavio Salvador wrote:
>>>>
>>>> On Mon, Aug 12, 2013 at 11:05 AM, Eric Nelson
>>>> <eric.nelson@boundarydevices.com> wrote:
>>>>>
>>>>> On 08/12/2013 05:50 AM, Otavio Salvador wrote:
>>>>>>
>>>>>> On Sat, Aug 10, 2013 at 7:12 PM, Eric Nelson
>>>>>> <eric.nelson@boundarydevices.com> wrote:
>>>>>>>
>>>>>>> Right now, gpu-viv-bin-mx6q-3.5.7-1.0.0-hfp.bin only supports hard
>>>>>>> float. Will the EABI (4.0.0) binaries continue to be supported or
>>>>>>> will there be a corresponding package of EABI binaries?
>>>>>>
>>>>>>
>>>>>> There's also a gpu-viv-bin-mx6q-3.5.7-1.0.0-sfp.bin and it is
>>>>>> taken in
>>>>>> case you're building for Soft Float-Point. It should 'Just Work'.
>>>>>>
>>>>>
>>>>> If that's the case, we can just push the patches onto our
>>>>> main branch and not deal with the old/new GPU package question.
>>>>
>>>> Not really as it will make impossible for your customers to use the
>>>> kernel with LTIB at 4.0.0 BSP (well, I'd love they stop using it
>>>> but...).
>>>>
>>>
>>> It's not just LTIB that's a question mark. The same comment
>>> goes for Debian, Buildroot, Timesys, Ubuntu, Arch or home-brew
>>> userspaces.
>>>
>>> If it's Freescale's recommendation that this GPU package is
>>> the **right** one for production use, our primary kernel
>>> branch should probably reflect that.
>>
>> I think the recommendation is to stay in their 'official' and 'test'
>> set of packages so I think it is better to have p12 support as patches
>> so it is clear it is something we are doing 'by ourselves'.

Okay. I didn't mean to open a can of worms here. I was just trying
to simplify things.

>
> 3.5.7-1.0.0 - is an alpha release. It does not have the same "stability"
> comparing with a GA release. It is not shared with *all* customers.
>

My bad. I figured since patches were being released into the wild,
this is officially "shared".

>>
>>> There's no reason someone using another userspace builder
>>> can't patch their process to update things.
>>
>> Well yes but it makes their life harder and a branch which won't work
>> with 'official' package set. So I think patches are the way to go for
>> now.
>>
>>> That said, I haven't quite heard this as Freescale's recommendation.
>>> Daiane, I don't suppose you want to stick your neck out...?
>>
>> Poor Daiane ;-)

I'm not trying to get you in trouble, Daiane. Just trying to grok
the current status.

>
> When I'm talking to meta-freescale I'm "Freescale". When I'm talking to
> guys inside Freescale, I'm "community".
>

But but but, we're all the "community", right?

We're all trying to get the best stuff into end-users' hands so they
can build great applications with a minimum of hassle!

> Here, I can only say public and official stuff. If you need Freescale's
> help, please enter a SR or a question on imx-community.
>
> =(
>

Sounds scary! Like there may be lawyers trolling there ;)

Regards,


Eric
Daiane Angolini - Aug. 12, 2013, 5:19 p.m.
On 08/12/2013 02:07 PM, Eric Nelson wrote:
> On 08/12/2013 09:45 AM, Daiane Angolini wrote:
>> On 08/12/2013 01:34 PM, Otavio Salvador wrote:
>>> On Mon, Aug 12, 2013 at 12:48 PM, Eric Nelson
>>> <eric.nelson@boundarydevices.com> wrote:
>>>> On 08/12/2013 08:18 AM, Otavio Salvador wrote:
>>>>>
>>>>> On Mon, Aug 12, 2013 at 11:05 AM, Eric Nelson
>>>>> <eric.nelson@boundarydevices.com> wrote:
>>>>>>
>>>>>> On 08/12/2013 05:50 AM, Otavio Salvador wrote:
>>>>>>>
>>>>>>> On Sat, Aug 10, 2013 at 7:12 PM, Eric Nelson
>>>>>>> <eric.nelson@boundarydevices.com> wrote:
>>>>>>>>
>>>>>>>> Right now, gpu-viv-bin-mx6q-3.5.7-1.0.0-hfp.bin only supports hard
>>>>>>>> float. Will the EABI (4.0.0) binaries continue to be supported or
>>>>>>>> will there be a corresponding package of EABI binaries?
>>>>>>>
>>>>>>>
>>>>>>> There's also a gpu-viv-bin-mx6q-3.5.7-1.0.0-sfp.bin and it is
>>>>>>> taken in
>>>>>>> case you're building for Soft Float-Point. It should 'Just Work'.
>>>>>>>
>>>>>>
>>>>>> If that's the case, we can just push the patches onto our
>>>>>> main branch and not deal with the old/new GPU package question.
>>>>>
>>>>> Not really as it will make impossible for your customers to use the
>>>>> kernel with LTIB at 4.0.0 BSP (well, I'd love they stop using it
>>>>> but...).
>>>>>
>>>>
>>>> It's not just LTIB that's a question mark. The same comment
>>>> goes for Debian, Buildroot, Timesys, Ubuntu, Arch or home-brew
>>>> userspaces.
>>>>
>>>> If it's Freescale's recommendation that this GPU package is
>>>> the **right** one for production use, our primary kernel
>>>> branch should probably reflect that.
>>>
>>> I think the recommendation is to stay in their 'official' and 'test'
>>> set of packages so I think it is better to have p12 support as patches
>>> so it is clear it is something we are doing 'by ourselves'.
>
> Okay. I didn't mean to open a can of worms here. I was just trying
> to simplify things.
>
>>
>> 3.5.7-1.0.0 - is an alpha release. It does not have the same "stability"
>> comparing with a GA release. It is not shared with *all* customers.
>>
>
> My bad. I figured since patches were being released into the wild,
> this is officially "shared".

If you try to look for the release under the normal freescale.com/imx 
you will not see it.

Please, don't ask me what's the difference.

>
>>>
>>>> There's no reason someone using another userspace builder
>>>> can't patch their process to update things.
>>>
>>> Well yes but it makes their life harder and a branch which won't work
>>> with 'official' package set. So I think patches are the way to go for
>>> now.
>>>
>>>> That said, I haven't quite heard this as Freescale's recommendation.
>>>> Daiane, I don't suppose you want to stick your neck out...?
>>>
>>> Poor Daiane ;-)
>
> I'm not trying to get you in trouble, Daiane. Just trying to grok
> the current status.

I know that ;)

>
>>
>> When I'm talking to meta-freescale I'm "Freescale". When I'm talking to
>> guys inside Freescale, I'm "community".
>>
>
> But but but, we're all the "community", right?
>
> We're all trying to get the best stuff into end-users' hands so they
> can build great applications with a minimum of hassle!
>
>> Here, I can only say public and official stuff. If you need Freescale's
>> help, please enter a SR or a question on imx-community.
>>
>> =(
>>
>
> Sounds scary! Like there may be lawyers trolling there ;)

lawyers, ninjas, gnomes, who knows?

>
> Regards,
>
>
> Eric
>
Post Lauren-RAA013 - Aug. 14, 2013, 6:09 p.m.
Just to clear up some confusion

For gpu-viv-bin-mx6 packages
- 3.0.35-4.1.0 is also p12 with some fixes on top of 3.5.7-1.0.0 alpha (but only swfp)

We are planning to update in a few weeks in master branch a new 3.5.7 gpu-viv-bin-mx6q that has same fixes from 3.0.35-4.1.0 release.

The question about using an alpha package on a production system in this case is not an issue since 3.0.35-4.1.0 is using updated p12 gpu-viv-bin-mx6q version that 3.5.7 used.

Hope this clears this up.  The 3.0.35-4.1.0 has a fix for the performance issue with window mode as shown in es2gears-x11 (not glxgears).  It does not fix the glmark2 crash with the new version on master (dylan version does not have crash) - there is a workaround posted on bugzilla.  There might be more fixes but I'll document them when the package is ready to go public.  

Lauren Post

-----Original Message-----
From: meta-freescale-bounces@yoctoproject.org [mailto:meta-freescale-bounces@yoctoproject.org] On Behalf Of Daiane Angolini
Sent: Monday, August 12, 2013 12:20 PM
To: Eric Nelson
Cc: meta-freescale Mailing List; Otavio Salvador
Subject: Re: [meta-freescale] [meta-fsl-arm-extra PATCH 2/2] linux-boundary: Add support to Vivante 4.6.9p12 GPU code

On 08/12/2013 02:07 PM, Eric Nelson wrote:
> On 08/12/2013 09:45 AM, Daiane Angolini wrote:
>> On 08/12/2013 01:34 PM, Otavio Salvador wrote:
>>> On Mon, Aug 12, 2013 at 12:48 PM, Eric Nelson 
>>> <eric.nelson@boundarydevices.com> wrote:
>>>> On 08/12/2013 08:18 AM, Otavio Salvador wrote:
>>>>>
>>>>> On Mon, Aug 12, 2013 at 11:05 AM, Eric Nelson 
>>>>> <eric.nelson@boundarydevices.com> wrote:
>>>>>>
>>>>>> On 08/12/2013 05:50 AM, Otavio Salvador wrote:
>>>>>>>
>>>>>>> On Sat, Aug 10, 2013 at 7:12 PM, Eric Nelson 
>>>>>>> <eric.nelson@boundarydevices.com> wrote:
>>>>>>>>
>>>>>>>> Right now, gpu-viv-bin-mx6q-3.5.7-1.0.0-hfp.bin only supports 
>>>>>>>> hard float. Will the EABI (4.0.0) binaries continue to be 
>>>>>>>> supported or will there be a corresponding package of EABI binaries?
>>>>>>>
>>>>>>>
>>>>>>> There's also a gpu-viv-bin-mx6q-3.5.7-1.0.0-sfp.bin and it is 
>>>>>>> taken in case you're building for Soft Float-Point. It should 
>>>>>>> 'Just Work'.
>>>>>>>
>>>>>>
>>>>>> If that's the case, we can just push the patches onto our main 
>>>>>> branch and not deal with the old/new GPU package question.
>>>>>
>>>>> Not really as it will make impossible for your customers to use 
>>>>> the kernel with LTIB at 4.0.0 BSP (well, I'd love they stop using 
>>>>> it but...).
>>>>>
>>>>
>>>> It's not just LTIB that's a question mark. The same comment goes 
>>>> for Debian, Buildroot, Timesys, Ubuntu, Arch or home-brew 
>>>> userspaces.
>>>>
>>>> If it's Freescale's recommendation that this GPU package is the 
>>>> **right** one for production use, our primary kernel branch should 
>>>> probably reflect that.
>>>
>>> I think the recommendation is to stay in their 'official' and 'test'
>>> set of packages so I think it is better to have p12 support as 
>>> patches so it is clear it is something we are doing 'by ourselves'.
>
> Okay. I didn't mean to open a can of worms here. I was just trying to 
> simplify things.
>
>>
>> 3.5.7-1.0.0 - is an alpha release. It does not have the same "stability"
>> comparing with a GA release. It is not shared with *all* customers.
>>
>
> My bad. I figured since patches were being released into the wild, 
> this is officially "shared".

If you try to look for the release under the normal freescale.com/imx you will not see it.

Please, don't ask me what's the difference.

>
>>>
>>>> There's no reason someone using another userspace builder can't 
>>>> patch their process to update things.
>>>
>>> Well yes but it makes their life harder and a branch which won't 
>>> work with 'official' package set. So I think patches are the way to 
>>> go for now.
>>>
>>>> That said, I haven't quite heard this as Freescale's recommendation.
>>>> Daiane, I don't suppose you want to stick your neck out...?
>>>
>>> Poor Daiane ;-)
>
> I'm not trying to get you in trouble, Daiane. Just trying to grok the 
> current status.

I know that ;)

>
>>
>> When I'm talking to meta-freescale I'm "Freescale". When I'm talking 
>> to guys inside Freescale, I'm "community".
>>
>
> But but but, we're all the "community", right?
>
> We're all trying to get the best stuff into end-users' hands so they 
> can build great applications with a minimum of hassle!
>
>> Here, I can only say public and official stuff. If you need 
>> Freescale's help, please enter a SR or a question on imx-community.
>>
>> =(
>>
>
> Sounds scary! Like there may be lawyers trolling there ;)

lawyers, ninjas, gnomes, who knows?

>
> Regards,
>
>
> Eric
>


--
Daiane

Patch

diff --git a/recipes-kernel/linux/linux-boundary-3.0.35/0001-ENGR00255688-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch b/recipes-kernel/linux/linux-boundary-3.0.35/0001-ENGR00255688-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch
new file mode 100644
index 0000000..9c7cd44
--- /dev/null
+++ b/recipes-kernel/linux/linux-boundary-3.0.35/0001-ENGR00255688-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch
@@ -0,0 +1,1040 @@ 
+From 46e3a6de5adb9379f9d6eef2c038c2f18637d407 Mon Sep 17 00:00:00 2001
+From: Loren Huang <b02279@freescale.com>
+Date: Mon, 25 Mar 2013 15:43:57 +0800
+Subject: [PATCH 1/6] ENGR00255688 4.6.9p11.1 [gpu]GPU Kernel driver
+ integration
+
+4.6.9p11.1 GPU kernel driver integration
+Cherry pick from imx_3.0.35
+
+Upstream-Status: Backport [3.5.7-1.0.0]
+
+Signed-off-by: Loren Huang <b02279@freescale.com>
+Acked-by: Lily Zhang
+---
+ drivers/mxc/gpu-viv/Kbuild                         |   2 +-
+ .../arch/XAQ2/hal/kernel/gc_hal_kernel_context.c   |   2 +-
+ .../arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c  |   7 +-
+ drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h     |   2 +-
+ drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c  |  53 ++++--
+ .../mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c   |   5 +-
+ drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c | 178 ++++++++++++---------
+ .../hal/kernel/gc_hal_kernel_video_memory.c        |   3 +-
+ .../gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h    |  13 +-
+ drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h |  25 +++
+ .../mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h    |  35 ++++
+ .../mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h    |   2 +-
+ .../hal/os/linux/kernel/gc_hal_kernel_driver.c     |   2 +-
+ .../hal/os/linux/kernel/gc_hal_kernel_linux.h      |   6 +
+ .../gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c |  82 +++++++++-
+ 15 files changed, 304 insertions(+), 113 deletions(-)
+
+diff --git a/drivers/mxc/gpu-viv/Kbuild b/drivers/mxc/gpu-viv/Kbuild
+index 0b18a7b..93b1259 100644
+--- a/drivers/mxc/gpu-viv/Kbuild
++++ b/drivers/mxc/gpu-viv/Kbuild
+@@ -1,6 +1,6 @@
+ ##############################################################################
+ #
+-#    Copyright (C) 2005 - 2012 by Vivante Corp.
++#    Copyright (C) 2005 - 2013 by Vivante Corp.
+ #
+ #    This program is free software; you can redistribute it and/or modify
+ #    it under the terms of the GNU General Public License as published by
+diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c
+index 22e1f27..24003e7 100644
+--- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c
++++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c
+@@ -471,7 +471,7 @@ _InitializeContextBuffer(
+     index += _SwitchPipe(Context, index, gcvPIPE_3D);
+ 
+     /* Current context pointer. */
+-#if gcdDEBUG 
++#if gcdDEBUG
+     index += _State(Context, index, 0x03850 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ #endif
+ 
+diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
+index a87259e..3829999 100644
+--- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
++++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
+@@ -232,7 +232,8 @@ _IdentifyHardware(
+     }
+ 
+     /* Exception for GC1000, revision 5035 &  GC800, revision 4612 */
+-    if (((Identity->chipModel == gcv1000) && (Identity->chipRevision == 0x5035))
++    if (((Identity->chipModel == gcv1000) && ((Identity->chipRevision == 0x5035)
++                                           || (Identity->chipRevision == 0x5036)))
+ 	 || ((Identity->chipModel == gcv800) && (Identity->chipRevision == 0x4612)))
+     {
+         Identity->superTileMode = 1;
+@@ -751,7 +752,7 @@ gckHARDWARE_Construct(
+     /* Initialize the fast clear. */
+     gcmkONERROR(gckHARDWARE_SetFastClear(hardware, -1, -1));
+ 
+-#if !gcdENABLE_128B_MERGE  
++#if !gcdENABLE_128B_MERGE
+ 
+     if (((((gctUINT32) (hardware->identity.chipMinorFeatures2)) >> (0 ? 21:21) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1)))))) == (0x1  & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))))
+     {
+@@ -1027,7 +1028,7 @@ gckHARDWARE_InitializeHardware(
+                                       0x00424,
+                                       baseAddress));
+ 
+-#if !VIVANTE_PROFILER 
++#if !VIVANTE_PROFILER
+     {
+         gctUINT32 data;
+ 
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
+index 1da80b7..5896e93 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
++++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
+@@ -186,7 +186,7 @@ typedef struct _gcsDATABASE
+     gctUINT64                           idle;
+ 
+     /* Pointer to database. */
+-    gcsDATABASE_RECORD_PTR              list;
++    gcsDATABASE_RECORD_PTR              list[48];
+ 
+ #if gcdSECURE_USER
+     /* Secure cache. */
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
+index 1fb18fb..bc5f083 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
++++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
+@@ -26,6 +26,9 @@
+ /*******************************************************************************
+ ***** Private fuctions ********************************************************/
+ 
++#define _GetSlot(database, x) \
++    (gctUINT32)(((gcmPTR_TO_UINT64(x) >> 7) % gcmCOUNTOF(database->list)))
++
+ /*******************************************************************************
+ **  gckKERNEL_NewDatabase
+ **
+@@ -56,6 +59,7 @@ gckKERNEL_NewDatabase(
+     gcsDATABASE_PTR database;
+     gctBOOL acquired = gcvFALSE;
+     gctSIZE_T slot;
++    gcsDATABASE_PTR existingDatabase;
+ 
+     gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
+ 
+@@ -63,6 +67,21 @@ gckKERNEL_NewDatabase(
+     gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+     acquired = gcvTRUE;
+ 
++    /* Compute the hash for the database. */
++    slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
++
++    /* Walk the hash list. */
++    for (existingDatabase = Kernel->db->db[slot];
++         existingDatabase != gcvNULL;
++         existingDatabase = existingDatabase->next)
++    {
++        if (existingDatabase->processID == ProcessID)
++        {
++            /* One process can't be added twice. */
++            gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
++        }
++    }
++
+     if (Kernel->db->freeDatabase != gcvNULL)
+     {
+         /* Allocate a database from the free list. */
+@@ -81,9 +100,6 @@ gckKERNEL_NewDatabase(
+         database = pointer;
+     }
+ 
+-    /* Compute the hash for the database. */
+-    slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
+-
+     /* Insert the database into the hash. */
+     database->next   = Kernel->db->db[slot];
+     Kernel->db->db[slot] = database;
+@@ -350,6 +366,7 @@ static gceSTATUS
+ gckKERNEL_NewRecord(
+     IN gckKERNEL Kernel,
+     IN gcsDATABASE_PTR Database,
++    IN gctUINT32 Slot,
+     OUT gcsDATABASE_RECORD_PTR * Record
+     )
+ {
+@@ -383,8 +400,8 @@ gckKERNEL_NewRecord(
+     }
+ 
+     /* Insert the record in the database. */
+-    record->next   = Database->list;
+-    Database->list = record;
++    record->next         = Database->list[Slot];
++    Database->list[Slot] = record;
+ 
+     /* Release the database mutex. */
+     gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+@@ -449,6 +466,7 @@ gckKERNEL_DeleteRecord(
+     gceSTATUS status;
+     gctBOOL acquired = gcvFALSE;
+     gcsDATABASE_RECORD_PTR record, previous;
++    gctUINT32 slot = _GetSlot(Database, Data);
+ 
+     gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
+                    Kernel, Database, Type, Data);
+@@ -458,8 +476,9 @@ gckKERNEL_DeleteRecord(
+         gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+     acquired = gcvTRUE;
+ 
++
+     /* Scan the database for this record. */
+-    for (record = Database->list, previous = gcvNULL;
++    for (record = Database->list[slot], previous = gcvNULL;
+          record != gcvNULL;
+          record = record->next
+     )
+@@ -490,7 +509,7 @@ gckKERNEL_DeleteRecord(
+     /* Remove record from database. */
+     if (previous == gcvNULL)
+     {
+-        Database->list = record->next;
++        Database->list[slot] = record->next;
+     }
+     else
+     {
+@@ -557,6 +576,7 @@ gckKERNEL_FindRecord(
+     gceSTATUS status;
+     gctBOOL acquired = gcvFALSE;
+     gcsDATABASE_RECORD_PTR record;
++    gctUINT32 slot = _GetSlot(Database, Data);
+ 
+     gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
+                    Kernel, Database, Type, Data);
+@@ -567,7 +587,7 @@ gckKERNEL_FindRecord(
+     acquired = gcvTRUE;
+ 
+     /* Scan the database for this record. */
+-    for (record = Database->list;
++    for (record = Database->list[slot];
+          record != gcvNULL;
+          record = record->next
+     )
+@@ -642,6 +662,7 @@ gckKERNEL_CreateProcessDB(
+ {
+     gceSTATUS status;
+     gcsDATABASE_PTR database = gcvNULL;
++    gctUINT32 i;
+ 
+     gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
+ 
+@@ -668,7 +689,11 @@ gckKERNEL_CreateProcessDB(
+     database->mapUserMemory.bytes      = 0;
+     database->mapUserMemory.maxBytes   = 0;
+     database->mapUserMemory.totalBytes = 0;
+-    database->list                  = gcvNULL;
++
++    for (i = 0; i < gcmCOUNTOF(database->list); i++)
++    {
++        database->list[i]              = gcvNULL;
++    }
+ 
+ #if gcdSECURE_USER
+     {
+@@ -848,7 +873,7 @@ gckKERNEL_AddProcessDB(
+     gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
+ 
+     /* Create a new record in the database. */
+-    gcmkONERROR(gckKERNEL_NewRecord(Kernel, database, &record));
++    gcmkONERROR(gckKERNEL_NewRecord(Kernel, database, _GetSlot(database, Pointer), &record));
+ 
+     /* Initialize the record. */
+     record->kernel   = Kernel;
+@@ -1086,6 +1111,7 @@ gckKERNEL_DestroyProcessDB(
+     gctPHYS_ADDR physical;
+     gcuVIDMEM_NODE_PTR node;
+     gckKERNEL kernel = Kernel;
++    gctUINT32 i;
+ 
+     gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
+ 
+@@ -1126,8 +1152,11 @@ gckKERNEL_DestroyProcessDB(
+                        ProcessID);
+     }
+ 
++    for(i = 0; i < gcmCOUNTOF(database->list); i++)
++    {
++
+     /* Walk all records. */
+-    for (record = database->list; record != gcvNULL; record = next)
++    for (record = database->list[i]; record != gcvNULL; record = next)
+     {
+         /* Next next record. */
+         next = record->next;
+@@ -1293,6 +1322,8 @@ gckKERNEL_DestroyProcessDB(
+                                            gcvNULL));
+     }
+ 
++    }
++
+     /* Delete the database. */
+     gcmkONERROR(gckKERNEL_DeleteDatabase(Kernel, database));
+ 
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
+index f78d096..217f7f1 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
++++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
+@@ -959,6 +959,8 @@ gckEVENT_AddList(
+     record->kernel = Event->kernel;
+ #endif
+ 
++    gcmkONERROR(__RemoveRecordFromProcessDB(Event, record));
++
+     /* Acquire the mutex. */
+     gcmkONERROR(gckOS_AcquireMutex(Event->os, Event->eventListMutex, gcvINFINITE));
+     acquired = gcvTRUE;
+@@ -1539,9 +1541,6 @@ gckEVENT_Submit(
+             gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
+             acquired = gcvFALSE;
+ 
+-            gcmkONERROR(__RemoveRecordFromProcessDB(Event,
+-                Event->queues[id].head));
+-
+ #if gcdNULL_DRIVER
+             /* Notify immediately on infinite hardware. */
+             gcmkONERROR(gckEVENT_Interrupt(Event, 1 << id));
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
+index 0c71e28..43c9297 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
++++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
+@@ -97,6 +97,43 @@ static gcsMirrorPageTable_PTR mirrorPageTable = gcvNULL;
+ static gctPOINTER mirrorPageTableMutex = gcvNULL;
+ #endif
+ 
++static void
++_WritePageEntry(
++    IN gctUINT32_PTR PageEntry,
++    IN gctUINT32     EntryValue
++    )
++{
++    static gctUINT16 data = 0xff00;
++
++    if (*(gctUINT8 *)&data == 0xff)
++    {
++        *PageEntry = gcmSWAB32(EntryValue);
++    }
++    else
++    {
++        *PageEntry = EntryValue;
++    }
++}
++
++static gctUINT32
++_ReadPageEntry(
++    IN gctUINT32_PTR PageEntry
++    )
++{
++    static gctUINT16 data = 0xff00;
++    gctUINT32 entryValue;
++
++    if (*(gctUINT8 *)&data == 0xff)
++    {
++        entryValue = *PageEntry;
++        return gcmSWAB32(entryValue);
++    }
++    else
++    {
++        return *PageEntry;
++    }
++}
++
+ static gceSTATUS
+ _FillPageTable(
+     IN gctUINT32_PTR PageTable,
+@@ -108,7 +145,7 @@ _FillPageTable(
+ 
+     for (i = 0; i < PageCount; i++)
+     {
+-        PageTable[i] = EntryValue;
++        _WritePageEntry(PageTable + i, EntryValue);
+     }
+ 
+     return gcvSTATUS_OK;
+@@ -132,16 +169,16 @@ _Link(
+         gctUINT32_PTR pageTable = Mmu->pageTableLogical;
+ 
+         /* Dispatch on node type. */
+-        switch (gcmENTRY_TYPE(pageTable[Index]))
++        switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[Index])))
+         {
+         case gcvMMU_SINGLE:
+             /* Set single index. */
+-            pageTable[Index] = (Next << 8) | gcvMMU_SINGLE;
++            _WritePageEntry(&pageTable[Index], (Next << 8) | gcvMMU_SINGLE);
+             break;
+ 
+         case gcvMMU_FREE:
+             /* Set index. */
+-            pageTable[Index + 1] = Next;
++            _WritePageEntry(&pageTable[Index + 1], Next);
+             break;
+ 
+         default:
+@@ -167,13 +204,13 @@ _AddFree(
+     if (Count == 1)
+     {
+         /* Initialize a single page node. */
+-        pageTable[Node] = (~((1U<<8)-1)) | gcvMMU_SINGLE;
++        _WritePageEntry(pageTable + Node, (~((1U<<8)-1)) | gcvMMU_SINGLE);
+     }
+     else
+     {
+         /* Initialize the node. */
+-        pageTable[Node + 0] = (Count << 8) | gcvMMU_FREE;
+-        pageTable[Node + 1] = ~0U;
++        _WritePageEntry(pageTable + Node + 0, (Count << 8) | gcvMMU_FREE);
++        _WritePageEntry(pageTable + Node + 1, ~0U);
+     }
+ 
+     /* Append the node. */
+@@ -196,7 +233,7 @@ _Collect(
+     for (i = 0; i < Mmu->pageTableEntries; ++i)
+     {
+         /* Dispatch based on type of page. */
+-        switch (gcmENTRY_TYPE(pageTable[i]))
++        switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[i])))
+         {
+         case gcvMMU_USED:
+             /* Used page, so close any open node. */
+@@ -229,10 +266,10 @@ _Collect(
+             }
+ 
+             /* Advance the count. */
+-            count += pageTable[i] >> 8;
++            count += _ReadPageEntry(&pageTable[i]) >> 8;
+ 
+             /* Advance the index into the page table. */
+-            i     += (pageTable[i] >> 8) - 1;
++            i     += (_ReadPageEntry(&pageTable[i]) >> 8) - 1;
+             break;
+ 
+         default:
+@@ -341,19 +378,20 @@ _FillFlatMapping(
+                 gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
+             }
+ 
+-            *(Mmu->mtlbLogical + mStart)
+-                      = stlb->physBase
+-                        /* 64KB page size */
+-                        | (1 << 2)
+-                        /* Ignore exception */
+-                        | (0 << 1)
+-                        /* Present */
+-                        | (1 << 0);
++            _WritePageEntry(Mmu->mtlbLogical + mStart,
++                            stlb->physBase
++                            /* 64KB page size */
++                            | (1 << 2)
++                            /* Ignore exception */
++                            | (0 << 1)
++                            /* Present */
++                            | (1 << 0)
++                            );
+ #if gcdMMU_TABLE_DUMP
+             gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
+                 __FUNCTION__, __LINE__,
+                 mStart,
+-                *(Mmu->mtlbLogical + mStart));
++                _ReadPageEntry(Mmu->mtlbLogical + mStart));
+ #endif
+ 
+             stlb->mtlbIndex = mStart;
+@@ -368,12 +406,12 @@ _FillFlatMapping(
+             while (sStart <= last)
+             {
+                 gcmkASSERT(!(start & gcdMMU_PAGE_64K_MASK));
+-                *(stlb->logical + sStart) = _SetPage(start);
++                _WritePageEntry(stlb->logical + sStart, _SetPage(start));
+ #if gcdMMU_TABLE_DUMP
+                 gckOS_Print("%s(%d): insert STLB[%d]: %08x\n",
+                     __FUNCTION__, __LINE__,
+                     sStart,
+-                    *(stlb->logical + sStart));
++                    _ReadPageEntry(stlb->logical + sStart));
+ #endif
+                 /* next page. */
+                 start += gcdMMU_PAGE_64K_SIZE;
+@@ -428,7 +466,7 @@ OnError:
+         if (pre->mtlbEntryNum != 0)
+         {
+             gcmkASSERT(pre->mtlbEntryNum == 1);
+-            *(Mmu->mtlbLogical + pre->mtlbIndex) = 0;
++            _WritePageEntry(Mmu->mtlbLogical + pre->mtlbIndex, 0);
+         }
+ 
+         gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, pre));
+@@ -493,8 +531,8 @@ _SetupDynamicSpace(
+ 
+     /* Initilization. */
+     pageTable      = Mmu->pageTableLogical;
+-    pageTable[0]   = (Mmu->pageTableEntries << 8) | gcvMMU_FREE;
+-    pageTable[1]   = ~0U;
++    _WritePageEntry(pageTable,     (Mmu->pageTableEntries << 8) | gcvMMU_FREE);
++    _WritePageEntry(pageTable + 1, ~0U);
+     Mmu->heapList  = 0;
+     Mmu->freeNodes = gcvFALSE;
+ 
+@@ -509,18 +547,20 @@ _SetupDynamicSpace(
+     /* Map to Master TLB. */
+     for (; i < gcdMMU_MTLB_ENTRY_NUM; i++)
+     {
+-        Mmu->mtlbLogical[i] = physical
+-                            /* 4KB page size */
+-                            | (0 << 2)
+-                            /* Ignore exception */
+-                            | (0 << 1)
+-                            /* Present */
+-                            | (1 << 0);
++        _WritePageEntry(Mmu->mtlbLogical + i,
++                        physical
++                        /* 4KB page size */
++                        | (0 << 2)
++                        /* Ignore exception */
++                        | (0 << 1)
++                        /* Present */
++                        | (1 << 0)
++                        );
+ #if gcdMMU_TABLE_DUMP
+         gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
+                 __FUNCTION__, __LINE__,
+                 i,
+-                *(Mmu->mtlbLogical + i));
++                _ReadPageEntry(Mmu->mtlbLogical + i));
+ #endif
+         physical += gcdMMU_STLB_4K_SIZE;
+     }
+@@ -645,18 +685,11 @@ _Construct(
+         pageTable      = mmu->pageTableLogical;
+ 
+ #if gcdMMU_CLEAR_VALUE
+-        {
+-            gctUINT32 i;
+-
+-            for (i = 0; i < mmu->pageTableEntries; ++i)
+-            {
+-                pageTable[i] = gcdMMU_CLEAR_VALUE;
+-            }
+-        }
++        _FillPageTable(pageTable, mmu->pageTableEntries, gcdMMU_CLEAR_VALUE);
+ #endif
+ 
+-        pageTable[0]   = (mmu->pageTableEntries << 8) | gcvMMU_FREE;
+-        pageTable[1]   = ~0U;
++        _WritePageEntry(pageTable,     (mmu->pageTableEntries << 8) | gcvMMU_FREE);
++        _WritePageEntry(pageTable + 1, ~0U);
+         mmu->heapList  = 0;
+         mmu->freeNodes = gcvFALSE;
+ 
+@@ -797,7 +830,7 @@ _Destroy(
+         if (pre->mtlbEntryNum != 0)
+         {
+             gcmkASSERT(pre->mtlbEntryNum == 1);
+-            *(Mmu->mtlbLogical + pre->mtlbIndex) = 0;
++            _WritePageEntry(Mmu->mtlbLogical + pre->mtlbIndex, 0);
+ #if gcdMMU_TABLE_DUMP
+             gckOS_Print("%s(%d): clean MTLB[%d]\n",
+                 __FUNCTION__, __LINE__,
+@@ -1044,7 +1077,7 @@ _AllocatePages(
+         for (index = Mmu->heapList; !gotIt && (index < Mmu->pageTableEntries);)
+         {
+             /* Check the node type. */
+-            switch (gcmENTRY_TYPE(pageTable[index]))
++            switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[index])))
+             {
+             case gcvMMU_SINGLE:
+                 /* Single odes are valid if we only need 1 page. */
+@@ -1056,13 +1089,13 @@ _AllocatePages(
+                 {
+                     /* Move to next node. */
+                     previous = index;
+-                    index    = pageTable[index] >> 8;
++                    index    = _ReadPageEntry(&pageTable[index]) >> 8;
+                 }
+                 break;
+ 
+             case gcvMMU_FREE:
+                 /* Test if the node has enough space. */
+-                if (PageCount <= (pageTable[index] >> 8))
++                if (PageCount <= (_ReadPageEntry(&pageTable[index]) >> 8))
+                 {
+                     gotIt = gcvTRUE;
+                 }
+@@ -1070,7 +1103,7 @@ _AllocatePages(
+                 {
+                     /* Move to next node. */
+                     previous = index;
+-                    index    = pageTable[index + 1];
++                    index    = _ReadPageEntry(&pageTable[index + 1]);
+                 }
+                 break;
+ 
+@@ -1099,36 +1132,36 @@ _AllocatePages(
+         }
+     }
+ 
+-    switch (gcmENTRY_TYPE(pageTable[index]))
++    switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[index])))
+     {
+     case gcvMMU_SINGLE:
+         /* Unlink single node from free list. */
+         gcmkONERROR(
+-            _Link(Mmu, previous, pageTable[index] >> 8));
++            _Link(Mmu, previous, _ReadPageEntry(&pageTable[index]) >> 8));
+         break;
+ 
+     case gcvMMU_FREE:
+         /* Check how many pages will be left. */
+-        left = (pageTable[index] >> 8) - PageCount;
++        left = (_ReadPageEntry(&pageTable[index]) >> 8) - PageCount;
+         switch (left)
+         {
+         case 0:
+             /* The entire node is consumed, just unlink it. */
+             gcmkONERROR(
+-                _Link(Mmu, previous, pageTable[index + 1]));
++                _Link(Mmu, previous, _ReadPageEntry(&pageTable[index + 1])));
+             break;
+ 
+         case 1:
+             /* One page will remain.  Convert the node to a single node and
+             ** advance the index. */
+-            pageTable[index] = (pageTable[index + 1] << 8) | gcvMMU_SINGLE;
++            _WritePageEntry(&pageTable[index], (_ReadPageEntry(&pageTable[index + 1]) << 8) | gcvMMU_SINGLE);
+             index ++;
+             break;
+ 
+         default:
+             /* Enough pages remain for a new node.  However, we will just adjust
+             ** the size of the current node and advance the index. */
+-            pageTable[index] = (left << 8) | gcvMMU_FREE;
++            _WritePageEntry(&pageTable[index], (left << 8) | gcvMMU_FREE);
+             index += left;
+             break;
+         }
+@@ -1232,35 +1265,32 @@ _FreePages(
+ #if gcdMMU_CLEAR_VALUE
+     if (Mmu->hardware->mmuVersion == 0)
+     {
+-        gctUINT32 i;
+-
+-        for (i = 0; i < PageCount; ++i)
+-        {
+-            pageTable[i] = gcdMMU_CLEAR_VALUE;
+-        }
++        _FillPageTable(pageTable, PageCount, gcdMMU_CLEAR_VALUE);
+     }
+ #endif
+ 
+     if (PageCount == 1)
+     {
+         /* Single page node. */
+-        pageTable[0] = (~((1U<<8)-1)) | gcvMMU_SINGLE
++        _WritePageEntry(pageTable,
++                        (~((1U<<8)-1)) | gcvMMU_SINGLE
+ #if gcdUSE_MMU_EXCEPTION
+-                     /* Enable exception */
+-                     | (1 << 1)
++                        /* Enable exception */
++                        | 1 << 1
+ #endif
+-                     ;
++                        );
+     }
+     else
+     {
+         /* Mark the node as free. */
+-        pageTable[0] = (PageCount << 8) | gcvMMU_FREE
++        _WritePageEntry(pageTable,
++                        (PageCount << 8) | gcvMMU_FREE
+ #if gcdUSE_MMU_EXCEPTION
+-                     /* Enable exception */
+-                     | (1 << 1)
++                        /* Enable exception */
++                        | 1 << 1
+ #endif
+-                     ;
+-        pageTable[1] = ~0U;
++                       );
++        _WritePageEntry(pageTable + 1, ~0U);
+ 
+ #if gcdUSE_MMU_EXCEPTION
+         /* Enable exception */
+@@ -1509,12 +1539,8 @@ gckMMU_SetPage(
+         data = _SetPage(PageAddress);
+     }
+ 
+-    if (Mmu->hardware->bigEndian)
+-    {
+-        data = gcmSWAB32(data);
+-    }
++    _WritePageEntry(PageEntry, data);
+ 
+-    *PageEntry = data;
+ #if gcdMIRROR_PAGETABLE
+     for (i = 0; i < mirrorPageTable->reference; i++)
+     {
+@@ -1526,11 +1552,11 @@ gckMMU_SetPage(
+ 
+             if (mmu->hardware->mmuVersion == 0)
+             {
+-                *pageEntry = PageAddress;
++                _WritePageEntry(pageEntry, PageAddress);
+             }
+             else
+             {
+-                *pageEntry = _SetPage(PageAddress);
++                _WritePageEntry(pageEntry, _SetPage(PageAddress));
+             }
+         }
+ 
+@@ -1734,7 +1760,7 @@ gckMMU_DumpPageTableEntry(
+               * gcdMMU_STLB_4K_ENTRY_NUM
+               + stlb;
+ 
+-        gcmkPRINT("    Page table entry = 0x%08X", pageTable[index]);
++        gcmkPRINT("    Page table entry = 0x%08X", _ReadPageEntry(pageTable + index));
+     }
+ 
+     gcmkFOOTER_NO();
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
+index d49aa64..8a442a2 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
++++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
+@@ -1027,7 +1027,8 @@ gckVIDMEM_AllocateLinear(
+     )
+     {
+         /* The left memory is for small memory.*/
+-        gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
++        status = gcvSTATUS_OUT_OF_MEMORY;
++        goto OnError;
+     }
+ #endif
+ 
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h
+index 496276e..06eea79 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h
++++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h
+@@ -227,7 +227,8 @@ gcoOS_GetDisplayInfoEx(
+     );
+ 
+ gceSTATUS
+-gcoOS_GetNextDisplayInfoEx(
++gcoOS_GetNextDisplayInfoExByIndex(
++    IN gctINT Index,
+     IN HALNativeDisplayType Display,
+     IN HALNativeWindowType Window,
+     IN gctUINT DisplayInfoSize,
+@@ -274,15 +275,15 @@ gcoOS_SetDisplayVirtualEx(
+ 
+ gceSTATUS
+ gcoOS_SetSwapInterval(
+-	IN HALNativeDisplayType Display,
+-	IN gctINT Interval
++    IN HALNativeDisplayType Display,
++    IN gctINT Interval
+ );
+ 
+ gceSTATUS
+ gcoOS_GetSwapInterval(
+-	IN HALNativeDisplayType Display,
+-	IN gctINT_PTR Min,
+-	IN gctINT_PTR Max
++    IN HALNativeDisplayType Display,
++    IN gctINT_PTR Min,
++    IN gctINT_PTR Max
+ );
+ 
+ gceSTATUS
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
+index d441d1d..249b61b 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
++++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
+@@ -1430,6 +1430,16 @@ typedef enum _gceTEXTURE_FACE
+ }
+ gceTEXTURE_FACE;
+ 
++#if gcdFORCE_MIPMAP
++typedef enum
++{
++    gcvForceMipDisabled  = 0,
++    gcvForceMipEnable    = 1,
++    gcvForceMipGenerated = 2,
++    gcvForceMipNever     = 3,
++}gceFORCE_MIPMAP;
++#endif
++
+ typedef struct _gcsTEXTURE
+ {
+     /* Addressing modes. */
+@@ -1446,6 +1456,10 @@ typedef struct _gcsTEXTURE
+     gceTEXTURE_FILTER           mipFilter;
+     gctUINT                     anisoFilter;
+     gctBOOL                     forceTopLevel;
++    gctBOOL                     autoMipmap;
++#if gcdFORCE_MIPMAP
++    gceFORCE_MIPMAP             forceMipmap;
++#endif
+     /* Level of detail. */
+     gctFIXED_POINT              lodBias;
+     gctFIXED_POINT              lodMin;
+@@ -1479,7 +1493,18 @@ gceSTATUS
+ gcoTEXTURE_Destroy(
+     IN gcoTEXTURE Texture
+     );
++#if gcdFORCE_MIPMAP
++gceSTATUS
++gcoTEXTURE_DestroyForceMipmap(
++    IN gcoTEXTURE Texture
++    );
+ 
++gceSTATUS
++gcoTEXTURE_GetMipLevels(
++    IN gcoTEXTURE Texture,
++    OUT gctINT * levels
++    );
++#endif
+ /* Replace a mipmap in gcoTEXTURE object. */
+ gceSTATUS
+ gcoTEXTURE_ReplaceMipMap(
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
+index 86e9133..afe83d0 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
++++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
+@@ -114,6 +114,30 @@
+ #define COMMAND_PROCESSOR_VERSION               1
+ 
+ /*
++    gcdDUMP_KEY
++
++        Set this to a string that appears in 'cat /proc/<pid>/cmdline'. E.g. 'camera'.
++        HAL will create dumps for the processes matching this key.
++*/
++#ifndef gcdDUMP_KEY
++#   define gcdDUMP_KEY                          "process"
++#endif
++
++/*
++    gcdDUMP_PATH
++
++        The dump file location. Some processes cannot write to the sdcard.
++        Try apps' data dir, e.g. /data/data/com.android.launcher
++*/
++#ifndef gcdDUMP_PATH
++#if defined(ANDROID)
++#   define gcdDUMP_PATH                         "/mnt/sdcard/"
++#else
++#   define gcdDUMP_PATH                         "./"
++#endif
++#endif
++
++/*
+     gcdDUMP
+ 
+         When set to 1, a dump of all states and memory uploads, as well as other
+@@ -342,6 +366,17 @@
+ #endif
+ 
+ /*
++    gcdUSER_HEAP_ALLOCATOR
++
++        Set to 1 to enable user mode heap allocator for fast memory allocation
++        and destroying. Otherwise, memory allocation/destroying in user mode
++        will be directly managed by system. Only for linux for now.
++*/
++#ifndef gcdUSER_HEAP_ALLOCATOR
++#   define gcdUSER_HEAP_ALLOCATOR               1
++#endif
++
++/*
+     gcdHEAP_SIZE
+ 
+         Set the allocation size for the internal heaps.  Each time a heap is
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
+index 2881604..808fde0 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
++++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
+@@ -28,7 +28,7 @@
+ 
+ #define gcvVERSION_PATCH        9
+ 
+-#define gcvVERSION_BUILD     1210
++#define gcvVERSION_BUILD     4651
+ 
+ #define gcvVERSION_DATE      __DATE__
+ 
+diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
+index 4e3819c..2ed3d0e 100644
+--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
++++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
+@@ -663,7 +663,7 @@ static int drv_mmap(
+ 
+ #if !gcdPAGED_MEMORY_CACHEABLE
+     vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+-    vma->vm_flags    |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND;
++    vma->vm_flags    |= gcdVM_FLAGS;
+ #endif
+     vma->vm_pgoff     = 0;
+ 
+diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
+index 9c0bcd5..3c148f6 100644
+--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
++++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
+@@ -73,6 +73,12 @@
+ 
+ #define GetPageCount(size, offset) 	((((size) + ((offset) & ~PAGE_CACHE_MASK)) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT)
+ 
++#if LINUX_VERSION_CODE >= KERNEL_VERSION (3,7,0)
++#define gcdVM_FLAGS (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP)
++#else
++#define gcdVM_FLAGS (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED)
++#endif
++
+ static inline gctINT
+ GetOrder(
+ 	IN gctINT numPages
+diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
+index c07ded8..9c2bae6 100644
+--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
++++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
+@@ -869,6 +869,60 @@ _UnmapUserLogical(
+ #endif
+ }
+ 
++gceSTATUS
++_QueryProcessPageTable(
++    IN gctPOINTER Logical,
++    OUT gctUINT32 * Address
++    )
++{
++    spinlock_t *lock;
++    gctUINTPTR_T logical = (gctUINTPTR_T)Logical;
++    pgd_t *pgd;
++    pud_t *pud;
++    pmd_t *pmd;
++    pte_t *pte;
++
++    if (!current->mm)
++    {
++        return gcvSTATUS_NOT_FOUND;
++    }
++
++    pgd = pgd_offset(current->mm, logical);
++    if (pgd_none(*pgd) || pgd_bad(*pgd))
++    {
++        return gcvSTATUS_NOT_FOUND;
++    }
++
++    pud = pud_offset(pgd, logical);
++    if (pud_none(*pud) || pud_bad(*pud))
++    {
++        return gcvSTATUS_NOT_FOUND;
++    }
++
++    pmd = pmd_offset(pud, logical);
++    if (pmd_none(*pmd) || pmd_bad(*pmd))
++    {
++        return gcvSTATUS_NOT_FOUND;
++    }
++
++    pte = pte_offset_map_lock(current->mm, pmd, logical, &lock);
++    if (!pte)
++    {
++        return gcvSTATUS_NOT_FOUND;
++    }
++
++    if (!pte_present(*pte))
++    {
++        pte_unmap_unlock(pte, lock);
++        return gcvSTATUS_NOT_FOUND;
++    }
++
++    *Address = (pte_pfn(*pte) << PAGE_SHIFT) | (logical & ~PAGE_MASK);
++    pte_unmap_unlock(pte, lock);
++
++    return gcvSTATUS_OK;
++}
++
+ /*******************************************************************************
+ **
+ **  gckOS_Construct
+@@ -1106,6 +1160,9 @@ _CreateKernelVirtualMapping(
+                     numPages,
+                     0,
+                     PAGE_KERNEL);
++
++        /* Trigger a page fault. */
++        memset(addr, 0, numPages * PAGE_SIZE);
+     }
+ #else
+     struct page ** pages;
+@@ -1136,6 +1193,9 @@ _CreateKernelVirtualMapping(
+     /* ioremap() can't work on system memory since 2.6.38. */
+     addr = vmap(pages, numPages, 0, gcmkNONPAGED_MEMROY_PROT(PAGE_KERNEL));
+ 
++    /* Trigger a page fault. */
++    memset(addr, 0, numPages * PAGE_SIZE);
++
+     if (free)
+     {
+         kfree(pages);
+@@ -1540,7 +1600,7 @@ gckOS_MapMemory(
+ #else
+ #if !gcdPAGED_MEMORY_CACHEABLE
+         mdlMap->vma->vm_page_prot = gcmkPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot);
+-        mdlMap->vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED;
++        mdlMap->vma->vm_flags |= gcdVM_FLAGS;
+ #   endif
+         mdlMap->vma->vm_pgoff = 0;
+ 
+@@ -1987,7 +2047,7 @@ gckOS_AllocateNonPagedMemory(
+         }
+ #else
+         mdlMap->vma->vm_page_prot = gcmkNONPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot);
+-        mdlMap->vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED;
++        mdlMap->vma->vm_flags |= gcdVM_FLAGS;
+         mdlMap->vma->vm_pgoff = 0;
+ 
+         if (remap_pfn_range(mdlMap->vma,
+@@ -2367,12 +2427,18 @@ gckOS_GetPhysicalAddress(
+     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+     gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+ 
+-    /* Get current process ID. */
+-    processID = _GetProcessID();
++    /* Query page table of current process first. */
++    status = _QueryProcessPageTable(Logical, Address);
+ 
+-    /* Route through other function. */
+-    gcmkONERROR(
+-        gckOS_GetPhysicalAddressProcess(Os, Logical, processID, Address));
++    if (gcmIS_ERROR(status))
++    {
++        /* Get current process ID. */
++        processID = _GetProcessID();
++
++        /* Route through other function. */
++        gcmkONERROR(
++            gckOS_GetPhysicalAddressProcess(Os, Logical, processID, Address));
++    }
+ 
+     /* Success. */
+     gcmkFOOTER_ARG("*Address=0x%08x", *Address);
+@@ -4139,7 +4205,7 @@ gckOS_LockPages(
+             return gcvSTATUS_OUT_OF_RESOURCES;
+         }
+ 
+-        mdlMap->vma->vm_flags |= VM_RESERVED;
++        mdlMap->vma->vm_flags |= gcdVM_FLAGS;
+ #if !gcdPAGED_MEMORY_CACHEABLE
+         if (Cacheable == gcvFALSE)
+         {
+-- 
+1.8.3.2
+
diff --git a/recipes-kernel/linux/linux-boundary-3.0.35/0002-ENGR00265465-gpu-Add-global-value-for-minimum-3D-clo.patch b/recipes-kernel/linux/linux-boundary-3.0.35/0002-ENGR00265465-gpu-Add-global-value-for-minimum-3D-clo.patch
new file mode 100644
index 0000000..5725ab7
--- /dev/null
+++ b/recipes-kernel/linux/linux-boundary-3.0.35/0002-ENGR00265465-gpu-Add-global-value-for-minimum-3D-clo.patch
@@ -0,0 +1,62 @@ 
+From 2df4dba8faa9a781a5a1c6c09d646d2b692c9a0c Mon Sep 17 00:00:00 2001
+From: Loren Huang <b02279@freescale.com>
+Date: Tue, 4 Jun 2013 15:08:15 +0800
+Subject: [PATCH 2/6] ENGR00265465 gpu:Add global value for minimum 3D clock
+ export
+
+Add global value gpu3DMinClock so that minimum 3D clock can be change by user.
+When gpu min clock is too low, it may cause IPU starvation issue in certain case.
+Use echo x > /sys/module/galcore/parameters/gpu3DMinClock to change it.
+
+Cherry-pick from 3.0.35 branch.
+
+Upstream-Status: Backport [3.5.7-1.0.0]
+
+Signed-off-by: Loren Huang <b02279@freescale.com>
+Acked-by: Lily Zhang
+---
+ drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c | 6 +++++-
+ drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c    | 3 +++
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
+index 3829999..ebd36fe 100644
+--- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
++++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
+@@ -36,6 +36,7 @@ typedef struct _gcsiDEBUG_REGISTERS
+ }
+ gcsiDEBUG_REGISTERS;
+ 
++extern int gpu3DMinClock;
+ /******************************************************************************\
+ ********************************* Support Code *********************************
+ \******************************************************************************/
+@@ -4630,7 +4631,10 @@ gckHARDWARE_GetFscaleValue(
+     )
+ {
+     *FscaleValue = Hardware->powerOnFscaleVal;
+-    *MinFscaleValue = 1;
++    if ((gpu3DMinClock > 0) && (gpu3DMinClock <= 64) && (Hardware->core == gcvCORE_MAJOR))
++        *MinFscaleValue = gpu3DMinClock;
++    else
++        *MinFscaleValue = 1;
+     *MaxFscaleValue = 64;
+ 
+     return gcvSTATUS_OK;
+diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
+index 2ed3d0e..64cace1 100644
+--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
++++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
+@@ -146,6 +146,9 @@ module_param(logFileSize,uint, 0644);
+ static int showArgs = 0;
+ module_param(showArgs, int, 0644);
+ 
++int gpu3DMinClock = 0;
++module_param(gpu3DMinClock, int, 0644);
++
+ #if ENABLE_GPU_CLOCK_BY_DRIVER
+     unsigned long coreClock = 156000000;
+     module_param(coreClock, ulong, 0644);
+-- 
+1.8.3.2
+
diff --git a/recipes-kernel/linux/linux-boundary-3.0.35/0003-ENGR00261814-4-gpu-use-new-PU-power-on-off-interface.patch b/recipes-kernel/linux/linux-boundary-3.0.35/0003-ENGR00261814-4-gpu-use-new-PU-power-on-off-interface.patch
new file mode 100644
index 0000000..23a415d
--- /dev/null
+++ b/recipes-kernel/linux/linux-boundary-3.0.35/0003-ENGR00261814-4-gpu-use-new-PU-power-on-off-interface.patch
@@ -0,0 +1,53 @@ 
+From 1579de9397783ab5321c80f1e76661653ef38ccd Mon Sep 17 00:00:00 2001
+From: Robin Gong <b38343@freescale.com>
+Date: Thu, 9 May 2013 11:45:55 +0800
+Subject: [PATCH 3/6] ENGR00261814-4 gpu: use new PU power on/off interface
+
+use new PU power on/off interface in GPU driver
+
+Upstream-Status: Backport [3.5.7-1.0.0]
+
+Signed-off-by: Robin Gong <b38343@freescale.com>
+Acked-by: Lily Zhang
+---
+ .../mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c   | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
+index 9c2bae6..dfbc699 100644
+--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
++++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
+@@ -6819,8 +6819,13 @@ gckOS_SetGPUPower(
+     }
+ 	if((Power == gcvTRUE) && (oldPowerState == gcvFALSE))
+ 	{
+-		if(!IS_ERR(Os->device->gpu_regulator))
+-            regulator_enable(Os->device->gpu_regulator);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)		
++	    if(!IS_ERR(Os->device->gpu_regulator))
++            	regulator_enable(Os->device->gpu_regulator);
++#else
++	    imx_gpc_power_up_pu(true);
++#endif
++
+ #ifdef CONFIG_PM
+ 		pm_runtime_get_sync(Os->device->pmdev);
+ #endif
+@@ -6930,8 +6935,13 @@ gckOS_SetGPUPower(
+ #ifdef CONFIG_PM
+ 		pm_runtime_put_sync(Os->device->pmdev);
+ #endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)		
+ 		if(!IS_ERR(Os->device->gpu_regulator))
+-            regulator_disable(Os->device->gpu_regulator);
++			regulator_disable(Os->device->gpu_regulator);
++#else
++    		imx_gpc_power_up_pu(false);
++#endif
+ 	}
+     /* TODO: Put your code here. */
+     gcmkFOOTER_NO();
+-- 
+1.8.3.2
+
diff --git a/recipes-kernel/linux/linux-boundary-3.0.35/0004-ENGR00264288-1-GPU-Integrate-4.6.9p12-release-kernel.patch b/recipes-kernel/linux/linux-boundary-3.0.35/0004-ENGR00264288-1-GPU-Integrate-4.6.9p12-release-kernel.patch
new file mode 100644
index 0000000..08ca88a
--- /dev/null
+++ b/recipes-kernel/linux/linux-boundary-3.0.35/0004-ENGR00264288-1-GPU-Integrate-4.6.9p12-release-kernel.patch
@@ -0,0 +1,2006 @@ 
+From c090a0238315094d245de2503b6f9a5bce0bda03 Mon Sep 17 00:00:00 2001
+From: Loren Huang <b02279@freescale.com>
+Date: Mon, 27 May 2013 17:45:48 +0800
+Subject: [PATCH 4/6] ENGR00264288-1 [GPU]Integrate 4.6.9p12 release kernel
+ part code
+
+Integrate 4.6.9p12 release kernel part code.
+Cherry-pick from 3.0.35 branch.
+
+Upstream-Status: Backport [3.5.7-1.0.0]
+
+Signed-off-by: Loren Huang <b02279@freescale.com>
+Acked-by: Lily Zhang
+---
+ .../GC350/hal/kernel/gc_hal_kernel_hardware_vg.c   |  63 +++-
+ .../GC350/hal/kernel/gc_hal_kernel_hardware_vg.h   |   2 +
+ .../arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c  | 174 ++++++++---
+ .../arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h  |   2 +
+ drivers/mxc/gpu-viv/config                         |   1 -
+ drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c     | 329 +++++++--------------
+ .../mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c |   6 +-
+ .../gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c  |  14 +-
+ drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c  |   6 +-
+ drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c | 119 +++++++-
+ .../hal/kernel/gc_hal_kernel_video_memory.c        |   3 +
+ drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h        |   6 +
+ drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h   |  34 +--
+ .../mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h   |  20 +-
+ drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h |  35 ++-
+ drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h |  62 +---
+ drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h   |   7 -
+ .../mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h    |  31 +-
+ .../mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h    |   2 +-
+ drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h     |   6 +
+ .../hal/os/linux/kernel/gc_hal_kernel_device.c     |  13 +
+ .../hal/os/linux/kernel/gc_hal_kernel_device.h     |   1 +
+ .../hal/os/linux/kernel/gc_hal_kernel_driver.c     |  10 +-
+ .../gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c |  74 +++--
+ .../gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h |   3 +
+ 25 files changed, 574 insertions(+), 449 deletions(-)
+
+diff --git a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c
+index 4a6010d..70c2cd6 100644
+--- a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c
++++ b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c
+@@ -217,7 +217,6 @@ _IdentifyHardware(
+     return status;
+ }
+ 
+-#if gcdPOWER_MANAGEMENT
+ static gctTHREADFUNCRESULT gctTHREADFUNCTYPE
+ _TimeIdleThread(
+     gctTHREADFUNCPARAMETER ThreadParameter
+@@ -262,8 +261,6 @@ _TimeIdleThread(
+     }
+     return 0;
+ }
+-#endif
+-
+ 
+ /******************************************************************************\
+ ****************************** gckVGHARDWARE API code *****************************
+@@ -309,6 +306,7 @@ gckVGHARDWARE_Construct(
+     do
+     {
+         gcmkERR_BREAK(gckOS_SetGPUPower(Os, gcvCORE_VG, gcvTRUE, gcvTRUE));
++
+         status = _ResetGPU(Os);
+ 
+         if (status != gcvSTATUS_OK)
+@@ -368,14 +366,17 @@ gckVGHARDWARE_Construct(
+ 
+         gcmkERR_BREAK(gckOS_CreateMutex(Os, &hardware->powerMutex));
+         gcmkERR_BREAK(gckOS_CreateSignal(Os, gcvFALSE, &hardware->idleSignal));
+-#if gcdPOWER_MANAGEMENT
++
++        /* Enable power management by default. */
++        hardware->powerManagement = gcvTRUE;
++
+         gcmkERR_BREAK(gckOS_StartThread(
+             hardware->os,
+             _TimeIdleThread,
+             hardware,
+             &hardware->timeIdleThread
+             ));
+-#endif
++
+         /* Return pointer to the gckVGHARDWARE object. */
+         *Hardware = hardware;
+ 
+@@ -395,6 +396,8 @@ gckVGHARDWARE_Construct(
+         gcmkVERIFY_OK(gckOS_Free(Os, hardware));
+     }
+ 
++    gcmkVERIFY_OK(gckOS_SetGPUPower(Os, gcvCORE_VG, gcvFALSE, gcvFALSE));
++
+     gcmkFOOTER();
+     /* Return the status. */
+     return status;
+@@ -425,11 +428,10 @@ gckVGHARDWARE_Destroy(
+     /* Verify the arguments. */
+     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ 
+-#if gcdPOWER_MANAGEMENT
+     Hardware->killThread  = gcvTRUE;
+     gcmkVERIFY_OK(gckOS_Signal(Hardware->os, Hardware->idleSignal, gcvTRUE));
+     gcmkVERIFY_OK(gckOS_StopThread(Hardware->os, Hardware->timeIdleThread));
+-#endif
++
+     /* Mark the object as unknown. */
+     Hardware->object.type = gcvOBJ_UNKNOWN;
+ 
+@@ -1432,7 +1434,6 @@ gckVGHARDWARE_ReadInterrupt(
+     return status;
+ }
+ 
+-#if gcdPOWER_MANAGEMENT
+ static gceSTATUS _CommandStall(
+     gckVGHARDWARE Hardware)
+ {
+@@ -1477,7 +1478,6 @@ static gceSTATUS _CommandStall(
+     /* Return the status. */
+     return status;
+ }
+-#endif
+ 
+ /*******************************************************************************
+ **
+@@ -1500,7 +1500,6 @@ gckVGHARDWARE_SetPowerManagementState(
+     IN gceCHIPPOWERSTATE State
+     )
+ {
+-#if gcdPOWER_MANAGEMENT
+     gceSTATUS status;
+     gckVGCOMMAND command = gcvNULL;
+     gckOS os;
+@@ -1600,6 +1599,12 @@ gckVGHARDWARE_SetPowerManagementState(
+     command = Hardware->kernel->command;
+     gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
+ 
++    if (Hardware->powerManagement == gcvFALSE)
++    {
++        gcmkFOOTER_NO();
++        return gcvSTATUS_OK;
++    }
++
+     /* Start profiler. */
+     gcmkPROFILE_INIT(freq, time);
+ 
+@@ -1914,10 +1919,6 @@ OnError:
+     /* Return the status. */
+     gcmkFOOTER();
+     return status;
+-#else /* gcdPOWER_MANAGEMENT */
+-    /* Do nothing */
+-    return gcvSTATUS_OK;
+-#endif
+ }
+ 
+ /*******************************************************************************
+@@ -1955,6 +1956,40 @@ gckVGHARDWARE_QueryPowerManagementState(
+     return gcvSTATUS_OK;
+ }
+ 
++/*******************************************************************************
++**
++**  gckVGHARDWARE_SetPowerManagement
++**
++**  Configure GPU power management function.
++**  Only used in driver initialization stage.
++**
++**  INPUT:
++**
++**      gckVGHARDWARE Harwdare
++**          Pointer to an gckHARDWARE object.
++**
++**      gctBOOL PowerManagement
++**          Power Mangement State.
++**
++*/
++gceSTATUS
++gckVGHARDWARE_SetPowerManagement(
++    IN gckVGHARDWARE Hardware,
++    IN gctBOOL PowerManagement
++    )
++{
++    gcmkHEADER_ARG("Hardware=0x%x", Hardware);
++
++    /* Verify the arguments. */
++    gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
++
++    Hardware->powerManagement = PowerManagement;
++
++    /* Success. */
++    gcmkFOOTER_NO();
++    return gcvSTATUS_OK;
++}
++
+ gceSTATUS
+ gckVGHARDWARE_SetPowerOffTimeout(
+     IN gckVGHARDWARE  Hardware,
+diff --git a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h
+index 83a603e..16b81ae 100644
+--- a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h
++++ b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h
+@@ -66,6 +66,8 @@ struct _gckVGHARDWARE
+     gctTHREAD                   timeIdleThread;
+     gctBOOL                     killThread;
+     gctPOINTER                  pageTableDirty;
++
++    gctBOOL                     powerManagement;
+ };
+ 
+ #endif /* __gc_hal_kernel_hardware_h_ */
+diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
+index ebd36fe..00f3839 100644
+--- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
++++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
+@@ -176,6 +176,7 @@ _IdentifyHardware(
+         Identity->chipMinorFeatures1 = 0;
+         Identity->chipMinorFeatures2 = 0;
+         Identity->chipMinorFeatures3 = 0;
++        Identity->chipMinorFeatures4 = 0;
+     }
+     else
+     {
+@@ -207,13 +208,20 @@ _IdentifyHardware(
+                 gckOS_ReadRegisterEx(Os, Core,
+                                      0x00088,
+                                      &Identity->chipMinorFeatures3));
++
++            /* Read chip minor featuress register #4. */
++            gcmkONERROR(
++                gckOS_ReadRegisterEx(Os, Core,
++                                     0x00094,
++                                     &Identity->chipMinorFeatures4));
+         }
+         else
+         {
+-            /* Chip doesn't has minor features register #1 or 2 or 3. */
++            /* Chip doesn't has minor features register #1 or 2 or 3 or 4. */
+             Identity->chipMinorFeatures1 = 0;
+             Identity->chipMinorFeatures2 = 0;
+             Identity->chipMinorFeatures3 = 0;
++            Identity->chipMinorFeatures4 = 0;
+         }
+     }
+ 
+@@ -234,14 +242,14 @@ _IdentifyHardware(
+ 
+     /* Exception for GC1000, revision 5035 &  GC800, revision 4612 */
+     if (((Identity->chipModel == gcv1000) && ((Identity->chipRevision == 0x5035)
+-                                           || (Identity->chipRevision == 0x5036)))
++                                           || (Identity->chipRevision == 0x5036)
++                                           || (Identity->chipRevision == 0x5037)))
+ 	 || ((Identity->chipModel == gcv800) && (Identity->chipRevision == 0x4612)))
+     {
+         Identity->superTileMode = 1;
+     }
+ 
+ 
+-
+ 	/* Disable HZ when EZ is present for older chips. */
+ 	if (!((((gctUINT32) (Identity->chipFeatures)) >> (0 ? 16:16) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))))
+     {
+@@ -285,6 +293,10 @@ _IdentifyHardware(
+                    "Identity: chipMinorFeatures3=0x%08X",
+                    Identity->chipMinorFeatures3);
+ 
++    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
++                   "Identity: chipMinorFeatures4=0x%08X",
++                   Identity->chipMinorFeatures4);
++
+     /***************************************************************************
+     ** Get chip specs.
+     */
+@@ -576,7 +588,6 @@ OnError:
+     return status;
+ }
+ 
+-#if gcdPOWER_MANAGEMENT
+ static gceSTATUS
+ _IsGPUPresent(
+     IN gckHARDWARE Hardware
+@@ -631,7 +642,6 @@ OnError:
+     gcmkFOOTER();
+     return status;
+ }
+-#endif
+ 
+ /******************************************************************************\
+ ****************************** gckHARDWARE API code *****************************
+@@ -708,6 +718,7 @@ gckHARDWARE_Construct(
+ 
+     case gcv300:
+     case gcv320:
++    case gcv420:
+         hardware->type = gcvHARDWARE_2D;
+         /*set outstanding limit*/
+         gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00414, &axi_ot));
+@@ -795,6 +806,9 @@ gckHARDWARE_Construct(
+     hardware->linkQueue.count = 0;
+ #endif
+ 
++    /* Enable power management by default. */
++    hardware->powerManagement = gcvTRUE;
++
+     /* Return pointer to the gckHARDWARE object. */
+     *Hardware = hardware;
+ 
+@@ -1404,6 +1418,7 @@ gckHARDWARE_QueryChipIdentity(
+     Identity->chipMinorFeatures1 = Hardware->identity.chipMinorFeatures1;
+     Identity->chipMinorFeatures2 = Hardware->identity.chipMinorFeatures2;
+     Identity->chipMinorFeatures3 = Hardware->identity.chipMinorFeatures3;
++    Identity->chipMinorFeatures4 = Hardware->identity.chipMinorFeatures4;
+ 
+     /* Return chip specs. */
+     Identity->streamCount            = Hardware->identity.streamCount;
+@@ -3129,7 +3144,7 @@ gckHARDWARE_FlushMMU(
+             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+ 
+         buffer[9]
+-            = (((((gctUINT32) (~0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) &  ((((gctUINT32) (~0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) );
++            = (((((gctUINT32) (~0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) &  ((((gctUINT32) (~0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))));
+ 
+         /* Arm the PE-FE Semaphore. */
+         buffer[10]
+@@ -3660,7 +3675,7 @@ typedef enum
+ }
+ gcePOWER_FLAGS;
+ 
+-#if gcmIS_DEBUG(gcdDEBUG_TRACE) && gcdPOWER_MANAGEMENT
++#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+ static gctCONST_STRING
+ _PowerEnum(gceCHIPPOWERSTATE State)
+ {
+@@ -3709,7 +3724,6 @@ gckHARDWARE_SetPowerManagementState(
+     IN gceCHIPPOWERSTATE State
+     )
+ {
+-#if gcdPOWER_MANAGEMENT
+     gceSTATUS status;
+     gckCOMMAND command = gcvNULL;
+     gckOS os;
+@@ -3841,6 +3855,12 @@ gckHARDWARE_SetPowerManagementState(
+     command = Hardware->kernel->command;
+     gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
+ 
++    if (Hardware->powerManagement == gcvFALSE)
++    {
++        gcmkFOOTER_NO();
++        return gcvSTATUS_OK;
++    }
++
+     /* Start profiler. */
+     gcmkPROFILE_INIT(freq, time);
+ 
+@@ -4491,10 +4511,6 @@ OnError:
+     /* Return the status. */
+     gcmkFOOTER();
+     return status;
+-#else /* gcdPOWER_MANAGEMENT */
+-    /* Do nothing */
+-    return gcvSTATUS_OK;
+-#endif
+ }
+ 
+ /*******************************************************************************
+@@ -4532,6 +4548,40 @@ gckHARDWARE_QueryPowerManagementState(
+     return gcvSTATUS_OK;
+ }
+ 
++/*******************************************************************************
++**
++**  gckHARDWARE_SetPowerManagement
++**
++**  Configure GPU power management function.
++**  Only used in driver initialization stage.
++**
++**  INPUT:
++**
++**      gckHARDWARE Harwdare
++**          Pointer to an gckHARDWARE object.
++**
++**      gctBOOL PowerManagement
++**          Power Mangement State.
++**
++*/
++gceSTATUS
++gckHARDWARE_SetPowerManagement(
++    IN gckHARDWARE Hardware,
++    IN gctBOOL PowerManagement
++    )
++{
++    gcmkHEADER_ARG("Hardware=0x%x", Hardware);
++
++    /* Verify the arguments. */
++    gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
++
++    Hardware->powerManagement = PowerManagement;
++
++    /* Success. */
++    gcmkFOOTER_NO();
++    return gcvSTATUS_OK;
++}
++
+ #if gcdENABLE_FSCALE_VAL_ADJUST
+ gceSTATUS
+ gckHARDWARE_SetFscaleValue(
+@@ -4767,6 +4817,21 @@ OnError:
+                              GC_DEBUG_SIGNALS_##block##_Address, \
+                              &profiler->data))
+ 
++#define gcmkREAD_DEBUG_REGISTER_N(control, block, index, data) \
++    gcmkONERROR(\
++        gckOS_WriteRegisterEx(Hardware->os, \
++                              Hardware->core, \
++                              GC_DEBUG_CONTROL##control##_Address, \
++                              gcmSETFIELD(0, \
++                                          GC_DEBUG_CONTROL##control, \
++                                          block, \
++                                          index))); \
++    gcmkONERROR(\
++        gckOS_ReadRegisterEx(Hardware->os, \
++                             Hardware->core, \
++                             GC_DEBUG_SIGNALS_##block##_Address, \
++                             &data))
++
+ #define gcmkRESET_DEBUG_REGISTER(control, block) \
+     gcmkONERROR(\
+         gckOS_WriteRegisterEx(Hardware->os, \
+@@ -4857,6 +4922,9 @@ gckHARDWARE_QueryProfileRegisters(
+ {
+     gceSTATUS status;
+     gcsPROFILER_COUNTERS * profiler = Counters;
++    gctUINT i, clock;
++    gctUINT32 colorKilled, colorDrawn, depthKilled, depthDrawn;
++    gctUINT32 totalRead, totalWrite;
+ 
+     gcmkHEADER_ARG("Hardware=0x%x Counters=0x%x", Hardware, Counters);
+ 
+@@ -4867,16 +4935,6 @@ gckHARDWARE_QueryProfileRegisters(
+     gcmkONERROR(
+         gckOS_ReadRegisterEx(Hardware->os,
+                              Hardware->core,
+-                             0x00040,
+-                             &profiler->gpuTotalRead64BytesPerFrame));
+-    gcmkONERROR(
+-        gckOS_ReadRegisterEx(Hardware->os,
+-                             Hardware->core,
+-                             0x00044,
+-                             &profiler->gpuTotalWrite64BytesPerFrame));
+-    gcmkONERROR(
+-        gckOS_ReadRegisterEx(Hardware->os,
+-                             Hardware->core,
+                              0x00438,
+                              &profiler->gpuCyclesCounter));
+ 
+@@ -4892,8 +4950,63 @@ gckHARDWARE_QueryProfileRegisters(
+                              0x0007C,
+                              &profiler->gpuIdleCyclesCounter));
+ 
+-    if(Reset){
+ 
++    /* Read clock control register. */
++    gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
++                                     Hardware->core,
++                                     0x00000,
++                                     &clock));
++
++    profiler->gpuTotalRead64BytesPerFrame = 0;
++    profiler->gpuTotalWrite64BytesPerFrame = 0;
++    profiler->pe_pixel_count_killed_by_color_pipe = 0;
++    profiler->pe_pixel_count_killed_by_depth_pipe = 0;
++    profiler->pe_pixel_count_drawn_by_color_pipe = 0;
++    profiler->pe_pixel_count_drawn_by_depth_pipe = 0;
++
++     /* Walk through all avaiable pixel pipes. */
++    for (i = 0; i < Hardware->identity.pixelPipes; ++i)
++    {
++        /* Select proper pipe. */
++        gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
++                                           Hardware->core,
++                                           0x00000,
++                                           ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20))) | (((gctUINT32) ((gctUINT32) (i) & ((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20)))));
++
++        /* BW */
++        gcmkONERROR(
++        gckOS_ReadRegisterEx(Hardware->os,
++                             Hardware->core,
++                             0x00040,
++                             &totalRead));
++        gcmkONERROR(
++        gckOS_ReadRegisterEx(Hardware->os,
++                             Hardware->core,
++                             0x00044,
++                             &totalWrite));
++
++        profiler->gpuTotalRead64BytesPerFrame += totalRead;
++        profiler->gpuTotalWrite64BytesPerFrame += totalWrite;
++
++        /* PE */
++        gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &colorKilled));
++        gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &depthKilled));
++        gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &colorDrawn));
++        gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &depthDrawn));
++
++        profiler->pe_pixel_count_killed_by_color_pipe += colorKilled;
++        profiler->pe_pixel_count_killed_by_depth_pipe += depthKilled;
++        profiler->pe_pixel_count_drawn_by_color_pipe += colorDrawn;
++        profiler->pe_pixel_count_drawn_by_depth_pipe += depthDrawn;
++    }
++
++    /* Reset clock control register. */
++    gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
++                                      Hardware->core,
++                                      0x00000,
++                                      clock));
++
++    if(Reset){
+             /* Reset counters. */
+             gcmkONERROR(
+                 gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 1));
+@@ -4903,19 +5016,10 @@ gckHARDWARE_QueryProfileRegisters(
+                 gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00438, 0));
+             gcmkONERROR(
+                 gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00078, 0));
+-        }
+-    /* PE */
+-    gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+-gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &profiler->pe_pixel_count_killed_by_color_pipe));
+-    gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+-gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &profiler->pe_pixel_count_killed_by_depth_pipe));
+-    gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+-gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &profiler->pe_pixel_count_drawn_by_color_pipe));
+-    gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+-gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &profiler->pe_pixel_count_drawn_by_depth_pipe));
+-    if(Reset){     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
++            gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))
+-)); }
++));
++    }
+ 
+     /* SH */
+     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h
+index 517b35c..37226b7 100644
+--- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h
++++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h
+@@ -90,6 +90,8 @@ struct _gckHARDWARE
+ #if gcdLINK_QUEUE_SIZE
+     struct _gckLINKQUEUE        linkQueue;
+ #endif
++
++    gctBOOL                     powerManagement;
+ };
+ 
+ gceSTATUS
+diff --git a/drivers/mxc/gpu-viv/config b/drivers/mxc/gpu-viv/config
+index 1196efa..cdd143e 100644
+--- a/drivers/mxc/gpu-viv/config
++++ b/drivers/mxc/gpu-viv/config
+@@ -22,7 +22,6 @@
+ ARCH_TYPE                         ?= arm
+ SDK_DIR                           ?= $(AQROOT)/build/sdk
+ USE_3D_VG                         ?= 1
+-USE_POWER_MANAGEMENT              ?= 1
+ FORCE_ALL_VIDEO_MEMORY_CACHED     ?= 0
+ NONPAGED_MEMORY_CACHEABLE         ?= 0
+ NONPAGED_MEMORY_BUFFERABLE        ?= 1
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
+index 7964585..b7b0d28 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
++++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
+@@ -904,9 +904,6 @@ gckKERNEL_Dispatch(
+     gctSIGNAL   signal;
+ #endif
+ 
+-    gcsDATABASE_RECORD record;
+-    gctPOINTER    data;
+-
+     gcmkHEADER_ARG("Kernel=0x%x FromUser=%d Interface=0x%x",
+                    Kernel, FromUser, Interface);
+ 
+@@ -1940,249 +1937,133 @@ gckKERNEL_Dispatch(
+ #endif
+ 
+     case gcvHAL_GET_SHARED_INFO:
+-        bytes = (gctSIZE_T) Interface->u.GetSharedInfo.size;
+-
+-        if (Interface->u.GetSharedInfo.dataId != 0)
++        if (Interface->u.GetSharedInfo.data == gcvNULL)
+         {
+-            gcmkONERROR(gckKERNEL_FindProcessDB(Kernel,
+-                        Interface->u.GetSharedInfo.pid,
+-                        0,
+-                        gcvDB_SHARED_INFO,
+-                        gcmINT2PTR(Interface->u.GetSharedInfo.dataId),
+-                        &record));
+-
+-            /* find a record in db, check size */
+-            if (record.bytes != bytes)
+-            {
+-                /* Size change is not allowed */
+-                gcmkONERROR(gcvSTATUS_INVALID_DATA);
+-            }
+-
+-            /* fetch data */
+-            gcmkONERROR(gckOS_CopyToUserData(
+-                Kernel->os,
+-                record.physical,
+-                gcmUINT64_TO_PTR(Interface->u.GetSharedInfo.data),
+-                bytes
+-                ));
+-
++            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+         }
+-
+-        if ((node = gcmUINT64_TO_PTR(Interface->u.GetSharedInfo.node)) != gcvNULL)
++        else
+         {
+-            switch (Interface->u.GetSharedInfo.infoType)
+-                {
+-                case gcvVIDMEM_INFO_GENERIC:
+-                    { /* Generic data stored */
+-                        if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+-                        {
+-                            data = &node->VidMem.sharedInfo;
+-
+-                        }
+-                        else
+-                        {
+-                            data = &node->Virtual.sharedInfo;
+-                        }
++            gctUINT32 pid    = Interface->u.GetSharedInfo.pid;
++            gctUINT32 dataId = Interface->u.GetSharedInfo.dataId;
++            gctSIZE_T bytes  = Interface->u.GetSharedInfo.bytes;
++            gctPOINTER data  = Interface->u.GetSharedInfo.data;
++            gcsDATABASE_RECORD record;
+ 
+-                         gcmkONERROR(gckOS_CopyToUserData(
+-                             Kernel->os,
+-                             data,
+-                             gcmUINT64_TO_PTR(Interface->u.GetSharedInfo.nodeData),
+-                             sizeof(gcsVIDMEM_NODE_SHARED_INFO)
+-                             ));
+-                    }
+-                    break;
+-
+-                case gcvVIDMEM_INFO_DIRTY_RECTANGLE:
+-                    { /* Dirty rectangle stored */
+-                        gcsVIDMEM_NODE_SHARED_INFO *storedSharedInfo;
+-                        gcsVIDMEM_NODE_SHARED_INFO alignedSharedInfo;
+-
+-                        if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+-                        {
+-                            storedSharedInfo = &node->VidMem.sharedInfo;
+-                        }
+-                        else
+-                        {
+-                            storedSharedInfo = &node->Virtual.sharedInfo;
+-                        }
+-
+-                        /* Stored shared info holds the unaligned dirty rectangle.
+-                           Align it first.                                         */
+-
+-                        /* Hardware requires 64-byte aligned address, and 16x4 pixel aligned rectsize.
+-                           We simply align to 32 pixels which covers both 16- and 32-bpp formats. */
+-
+-                        /* Make sure we have a legit rectangle. */
+-                        gcmkASSERT((storedSharedInfo->RectSize.width != 0) && (storedSharedInfo->RectSize.height != 0));
+-
+-                        alignedSharedInfo.SrcOrigin.x = gcmALIGN_BASE(storedSharedInfo->SrcOrigin.x, 32);
+-                        alignedSharedInfo.RectSize.width = gcmALIGN((storedSharedInfo->RectSize.width + (storedSharedInfo->SrcOrigin.x - alignedSharedInfo.SrcOrigin.x)), 16);
+-
+-                        alignedSharedInfo.SrcOrigin.y = gcmALIGN_BASE(storedSharedInfo->SrcOrigin.y, 4);
+-                        alignedSharedInfo.RectSize.height = gcmALIGN((storedSharedInfo->RectSize.height + (storedSharedInfo->SrcOrigin.y - alignedSharedInfo.SrcOrigin.y)), 4);
+-
+-                        gcmkONERROR(gckOS_CopyToUserData(
+-                            Kernel->os,
+-                            &alignedSharedInfo,
+-                            gcmUINT64_TO_PTR(Interface->u.GetSharedInfo.nodeData),
+-                            sizeof(gcsVIDMEM_NODE_SHARED_INFO)
+-                            ));
+-
+-                        gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_KERNEL,
+-                                        "Node = %p, unaligned rectangle (l=%d, t=%d, w=%d, h=%d) aligned to (l=%d, t=%d, w=%d, h=%d)", node,
+-                                        storedSharedInfo->SrcOrigin.x, storedSharedInfo->SrcOrigin.y,
+-                                        storedSharedInfo->RectSize.width, storedSharedInfo->RectSize.height,
+-                                        alignedSharedInfo.SrcOrigin.x, alignedSharedInfo.SrcOrigin.y,
+-                                        alignedSharedInfo.RectSize.width, alignedSharedInfo.RectSize.height);
++            /* Find record. */
++            gcmkONERROR(
++                gckKERNEL_FindProcessDB(Kernel,
++                                        pid,
++                                        0,
++                                        gcvDB_SHARED_INFO,
++                                        gcmINT2PTR(dataId),
++                                        &record));
++
++            /* Check memory size. */
++            if (bytes < record.bytes)
++            {
++                /* Insufficient memory to hold shared data. */
++                gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
++            }
+ 
+-                        /* Rectangle */
+-                        storedSharedInfo->SrcOrigin.x =
+-                        storedSharedInfo->SrcOrigin.y =
+-                        storedSharedInfo->RectSize.width =
+-                        storedSharedInfo->RectSize.height = 0;
+-                    }
+-                    break;
+-                }
++            /* Copy to user. */
++            status = gckOS_CopyToUserData(Kernel->os,
++                                          record.physical,
++                                          data,
++                                          record.bytes);
++
++            /*
++             * Remove from process db.
++             * Every time when shared info is taken, the record is erased in
++             * kernel side.
++             */
++            gcmkVERIFY_OK(
++                gckKERNEL_RemoveProcessDB(Kernel,
++                                          pid,
++                                          gcvDB_SHARED_INFO,
++                                          gcmINT2PTR(dataId)));
++            /* Free existed data. */
++            gcmkVERIFY_OK(
++                gckOS_FreeMemory(Kernel->os, record.physical));
+         }
+         break;
+ 
+     case gcvHAL_SET_SHARED_INFO:
+-        bytes = (gctSIZE_T) Interface->u.SetSharedInfo.size;
+-
+-        if (Interface->u.SetSharedInfo.dataId != 0)
+         {
+-            status = gckKERNEL_FindProcessDB(Kernel, processID, 0,
+-                        gcvDB_SHARED_INFO,
+-                        gcmINT2PTR(Interface->u.SetSharedInfo.dataId),
+-                        &record);
+-
+-            if (status == gcvSTATUS_INVALID_DATA)
+-            {
+-                /* private data has not been created yet */
+-                /* Note: we count on DestoryProcessDB to free it */
+-                gcmkONERROR(gckOS_AllocateMemory(
+-                    Kernel->os,
+-                    bytes,
+-                    &data
+-                    ));
+-
+-                gcmkONERROR(
+-                    gckKERNEL_AddProcessDB(Kernel, processID,
+-                        gcvDB_SHARED_INFO,
+-                        gcmINT2PTR(Interface->u.SetSharedInfo.dataId),
+-                        data,
+-                        bytes
+-                        ));
+-            }
+-            else
++            gctUINT32 dataId = Interface->u.SetSharedInfo.dataId;
++            gctPOINTER data  = Interface->u.SetSharedInfo.data;
++            gctUINT32 bytes  = Interface->u.SetSharedInfo.bytes;
++            gctPOINTER memory = gcvNULL;
++            gcsDATABASE_RECORD record;
++
++            if (gcmIS_SUCCESS(gckKERNEL_FindProcessDB(Kernel,
++                                                     processID,
++                                                     0,
++                                                     gcvDB_SHARED_INFO,
++                                                     gcmINT2PTR(dataId),
++                                                     &record)))
+             {
+-                /* bail on other errors */
+-                gcmkONERROR(status);
+-
+-                /* find a record in db, check size */
+-                if (record.bytes != bytes)
++                /* Find a record with the same id. */
++                if (bytes != record.bytes)
+                 {
+-                    /* Size change is not allowed */
+-                    gcmkONERROR(gcvSTATUS_INVALID_DATA);
++                    /* Remove from process db. */
++                    gcmkVERIFY_OK(
++                        gckKERNEL_RemoveProcessDB(Kernel,
++                                                  processID,
++                                                  gcvDB_SHARED_INFO,
++                                                  gcmINT2PTR(dataId)));
++
++                    /* Free existed data. */
++                    gcmkVERIFY_OK(
++                        gckOS_FreeMemory(Kernel->os, record.physical));
+                 }
+-
+-                /* get storage address */
+-                data = record.physical;
+-            }
+-
+-            gcmkONERROR(gckOS_CopyFromUserData(
+-                Kernel->os,
+-                data,
+-                gcmUINT64_TO_PTR(Interface->u.SetSharedInfo.data),
+-                bytes
+-                ));
+-        }
+-
+-        if ((node = gcmUINT64_TO_PTR(Interface->u.SetSharedInfo.node)) != gcvNULL)
+-        {
+-            switch (Interface->u.SetSharedInfo.infoType)
++                else
+                 {
+-                case gcvVIDMEM_INFO_GENERIC:
+-                    { /* Generic data stored */
+-                        if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+-                        {
+-                            data = &node->VidMem.sharedInfo;
+-                        }
+-                        else
+-                        {
+-                            data = &node->Virtual.sharedInfo;
+-                        }
+-
+-                        gcmkONERROR(gckOS_CopyFromUserData(
+-                            Kernel->os,
+-                            data,
+-                            gcmUINT64_TO_PTR(Interface->u.SetSharedInfo.nodeData),
+-                            sizeof(gcsVIDMEM_NODE_SHARED_INFO)
+-                            ));
+-                    }
+-                    break;
++                    /* Re-use allocated memory. */
++                    memory = record.physical;
++                }
++            }
+ 
+-                case gcvVIDMEM_INFO_DIRTY_RECTANGLE:
+-                    { /* Dirty rectangle stored */
+-                        gcsVIDMEM_NODE_SHARED_INFO newSharedInfo;
+-                        gcsVIDMEM_NODE_SHARED_INFO *currentSharedInfo;
+-                        gctINT dirtyX, dirtyY, right, bottom;
+-
+-                        /* Expand the dirty rectangle stored in the node to include the rectangle passed in. */
+-                        gcmkONERROR(gckOS_CopyFromUserData(
+-                            Kernel->os,
+-                            &newSharedInfo,
+-                            gcmUINT64_TO_PTR(Interface->u.SetSharedInfo.nodeData),
+-                            gcmSIZEOF(gcsVIDMEM_NODE_SHARED_INFO)
+-                            ));
+-
+-                        if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+-                        {
+-                            currentSharedInfo = &node->VidMem.sharedInfo;
+-                        }
+-                        else
+-                        {
+-                            currentSharedInfo = &node->Virtual.sharedInfo;
+-                        }
++            if ((data == gcvNULL) || (bytes == 0))
++            {
++                /* Nothing to record. */
++                break;
++            }
+ 
+-                        gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_KERNEL, "Node = %p Stored rectangle (l=%d, t=%d, w=%d, h=%d)", node,
+-                                        currentSharedInfo->SrcOrigin.x, currentSharedInfo->SrcOrigin.y,
+-                                        currentSharedInfo->RectSize.width, currentSharedInfo->RectSize.height);
++            if (bytes > 1024)
++            {
++                /* Limite data size. */
++                gcmkONERROR(gcvSTATUS_TOO_COMPLEX);
++            }
+ 
+-                        gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_KERNEL, "To combine with (l=%d, t=%d, w=%d, h=%d)",
+-                                        newSharedInfo.SrcOrigin.x, newSharedInfo.SrcOrigin.y,
+-                                        newSharedInfo.RectSize.width, newSharedInfo.RectSize.height);
++            if (memory == gcvNULL)
++            {
++                /* Allocate memory for holding shared data. */
++                gcmkONERROR(
++                    gckOS_AllocateMemory(Kernel->os, bytes, &memory));
+ 
+-                        if ((currentSharedInfo->RectSize.width == 0) || (currentSharedInfo->RectSize.height == 0))
+-                        { /* Setting it for the first time */
+-                            currentSharedInfo->SrcOrigin.x = newSharedInfo.SrcOrigin.x;
+-                            currentSharedInfo->SrcOrigin.y = newSharedInfo.SrcOrigin.y;
+-                            currentSharedInfo->RectSize.width = newSharedInfo.RectSize.width;
+-                            currentSharedInfo->RectSize.height = newSharedInfo.RectSize.height;
+-                        }
+-                        else
+-                        {
+-                            /* Expand the stored rectangle to include newly locked rectangle */
+-                            dirtyX = (newSharedInfo.SrcOrigin.x < currentSharedInfo->SrcOrigin.x) ? newSharedInfo.SrcOrigin.x : currentSharedInfo->SrcOrigin.x;
+-                            right = gcmMAX((currentSharedInfo->SrcOrigin.x + currentSharedInfo->RectSize.width), (newSharedInfo.SrcOrigin.x + newSharedInfo.RectSize.width));
+-                            currentSharedInfo->RectSize.width = right - dirtyX;
+-                            currentSharedInfo->SrcOrigin.x = dirtyX;
+-
+-                            dirtyY = (newSharedInfo.SrcOrigin.y < currentSharedInfo->SrcOrigin.y) ? newSharedInfo.SrcOrigin.y : currentSharedInfo->SrcOrigin.y;
+-                            bottom = gcmMAX((currentSharedInfo->SrcOrigin.y + currentSharedInfo->RectSize.height), (newSharedInfo.SrcOrigin.y + newSharedInfo.RectSize.height));
+-                            currentSharedInfo->RectSize.height = bottom - dirtyY;
+-                            currentSharedInfo->SrcOrigin.y = dirtyY;
+-                        }
++                /* Add to process db. */
++                status = gckKERNEL_AddProcessDB(Kernel,
++                                                processID,
++                                                gcvDB_SHARED_INFO,
++                                                gcmINT2PTR(dataId),
++                                                memory,
++                                                bytes);
+ 
+-                        gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_KERNEL, "Combined rectangle (l=%d, t=%d, w=%d, h=%d)",
+-                                       currentSharedInfo->SrcOrigin.x, currentSharedInfo->SrcOrigin.y,
+-                                       currentSharedInfo->RectSize.width, currentSharedInfo->RectSize.height);
+-                    }
++                if (gcmIS_ERROR(status))
++                {
++                    /* Failed to add process db. Free allocated memory. */
++                    gcmkVERIFY_OK(gckOS_FreeMemory(Kernel->os, memory));
+                     break;
+                 }
+-        }
++            }
+ 
++            /* Copy shared data to kernel memory. */
++            gcmkONERROR(
++                gckOS_CopyFromUserData(Kernel->os,
++                                       memory,
++                                       data,
++                                       bytes));
++        }
+         break;
+ 
+     case gcvHAL_SET_FSCALE_VALUE:
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
+index 66ce0d1..9ee9ea1 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
++++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
+@@ -2047,14 +2047,14 @@ gckCOMMAND_Commit(
+         EventQueue = nextEventRecord;
+     }
+ 
+-#if gcdPOWER_MANAGEMENT
+-    if (Command->kernel->eventObj->queueHead == gcvNULL)
++    if (Command->kernel->eventObj->queueHead == gcvNULL
++     && Command->kernel->hardware->powerManagement == gcvTRUE
++    )
+     {
+         /* Commit done event by which work thread knows all jobs done. */
+         gcmkVERIFY_OK(
+             gckEVENT_CommitDone(Command->kernel->eventObj, gcvKERNEL_PIXEL));
+     }
+-#endif
+ 
+     /* Submit events. */
+     status = gckEVENT_Submit(Command->kernel->eventObj, gcvTRUE, gcvFALSE);
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c
+index 9685a5d..76c1c10 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c
++++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c
+@@ -1234,7 +1234,6 @@ _EventHandler_BusError(
+     return gcvSTATUS_OK;
+ }
+ 
+-#if gcdPOWER_MANAGEMENT
+ /******************************************************************************\
+ ****************************** Power Stall Handler *******************************
+ \******************************************************************************/
+@@ -1250,7 +1249,6 @@ _EventHandler_PowerStall(
+         Kernel->command->powerStallSignal,
+         gcvTRUE);
+ }
+-#endif
+ 
+ /******************************************************************************\
+ ******************************** Task Routines *********************************
+@@ -1965,15 +1963,12 @@ gcmDECLARE_INTERRUPT_HANDLER(COMMAND, 0)
+                             );
+                     }
+                 }
+-#if gcdPOWER_MANAGEMENT
+                 else
+                 {
+-
+                     status = gckVGHARDWARE_SetPowerManagementState(
+                                 Kernel->command->hardware, gcvPOWER_IDLE_BROADCAST
+                                 );
+                 }
+-#endif
+ 
+                 /* Break out of the loop. */
+                 break;
+@@ -2848,7 +2843,7 @@ gckVGCOMMAND_Construct(
+             _EventHandler_BusError
+             ));
+ 
+-#if gcdPOWER_MANAGEMENT
++
+         command->powerStallInt = 30;
+         /* Enable the interrupt. */
+         gcmkERR_BREAK(gckVGINTERRUPT_Enable(
+@@ -2856,7 +2851,6 @@ gckVGCOMMAND_Construct(
+             &command->powerStallInt,
+             _EventHandler_PowerStall
+             ));
+-#endif
+ 
+         /***********************************************************************
+         ** Task management initialization.
+@@ -3419,7 +3413,6 @@ gckVGCOMMAND_Commit(
+             gcvINFINITE
+             ));
+ 
+-#if gcdPOWER_MANAGEMENT
+         status = gckVGHARDWARE_SetPowerManagementState(
+             Command->hardware, gcvPOWER_ON_AUTO);
+ 
+@@ -3447,7 +3440,7 @@ gckVGCOMMAND_Commit(
+ 
+             break;
+         }
+-#endif
++
+         gcmkERR_BREAK(_FlushMMU(Command));
+ 
+         do
+@@ -3676,10 +3669,9 @@ gckVGCOMMAND_Commit(
+         }
+         while (gcvFALSE);
+ 
+-#if gcdPOWER_MANAGEMENT
+         gcmkVERIFY_OK(gckOS_ReleaseSemaphore(
+             Command->os, Command->powerSemaphore));
+-#endif
++
+         /* Release the mutex. */
+         gcmkCHECK_STATUS(gckOS_ReleaseMutex(
+             Command->os,
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
+index bc5f083..673d4f7 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
++++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
+@@ -1303,9 +1303,9 @@ gckKERNEL_DestroyProcessDB(
+                            gcmPTR2INT(record->data), status);
+             break;
+ 
+-                    case gcvDB_SHARED_INFO:
+-                        status = gckOS_FreeMemory(Kernel->os, record->physical);
+-                        break;
++        case gcvDB_SHARED_INFO:
++            status = gckOS_FreeMemory(Kernel->os, record->physical);
++            break;
+ 
+         default:
+             gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DATABASE,
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
+index 43c9297..c7f67c7 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
++++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
+@@ -97,6 +97,14 @@ static gcsMirrorPageTable_PTR mirrorPageTable = gcvNULL;
+ static gctPOINTER mirrorPageTableMutex = gcvNULL;
+ #endif
+ 
++typedef struct _gcsDynamicSpaceNode * gcsDynamicSpaceNode_PTR;
++typedef struct _gcsDynamicSpaceNode
++{
++    gctUINT32       start;
++    gctINT32        entries;
++}
++gcsDynamicSpaceNode;
++
+ static void
+ _WritePageEntry(
+     IN gctUINT32_PTR PageEntry,
+@@ -482,30 +490,117 @@ OnError:
+ }
+ 
+ static gceSTATUS
++_FindDynamicSpace(
++    IN gckMMU Mmu,
++    OUT gcsDynamicSpaceNode_PTR *Array,
++    OUT gctINT * Size
++    )
++{
++    gceSTATUS status = gcvSTATUS_OK;
++    gctPOINTER pointer = gcvNULL;
++    gcsDynamicSpaceNode_PTR array = gcvNULL;
++    gctINT size = 0;
++    gctINT i = 0, nodeStart = -1, nodeEntries = 0;
++
++    /* Allocate memory for the array. */
++    gcmkONERROR(gckOS_Allocate(Mmu->os,
++                               gcmSIZEOF(*array) * (gcdMMU_MTLB_ENTRY_NUM / 2),
++                               &pointer));
++
++    array = (gcsDynamicSpaceNode_PTR)pointer;
++
++    /* Loop all the entries. */
++    while (i < gcdMMU_MTLB_ENTRY_NUM)
++    {
++        if (!Mmu->mtlbLogical[i])
++        {
++            if (nodeStart < 0)
++            {
++                /* This is the first entry of the dynamic space. */
++                nodeStart   = i;
++                nodeEntries = 1;
++            }
++            else
++            {
++                /* Other entries of the dynamic space. */
++                nodeEntries++;
++            }
++        }
++        else if (nodeStart >= 0)
++        {
++            /* Save the previous node. */
++            array[size].start   = nodeStart;
++            array[size].entries = nodeEntries;
++            size++;
++
++            /* Reset the start. */
++            nodeStart   = -1;
++            nodeEntries = 0;
++        }
++
++        i++;
++    }
++
++    /* Save the previous node. */
++    if (nodeStart >= 0)
++    {
++        array[size].start   = nodeStart;
++        array[size].entries = nodeEntries;
++        size++;
++    }
++
++#if gcdMMU_TABLE_DUMP
++    for (i = 0; i < size; i++)
++    {
++        gckOS_Print("%s(%d): [%d]: start=%d, entries=%d.\n",
++                __FUNCTION__, __LINE__,
++                i,
++                array[i].start,
++                array[i].entries);
++    }
++#endif
++
++    *Array = array;
++    *Size  = size;
++
++    return gcvSTATUS_OK;
++
++OnError:
++    if (pointer != gcvNULL)
++    {
++        gckOS_Free(Mmu->os, pointer);
++    }
++
++    return status;
++}
++
++static gceSTATUS
+ _SetupDynamicSpace(
+     IN gckMMU Mmu
+     )
+ {
+     gceSTATUS status;
+-    gctINT i;
++    gcsDynamicSpaceNode_PTR nodeArray = gcvNULL;
++    gctINT i, nodeArraySize = 0;
+     gctUINT32 physical;
+-    gctINT numEntries;
++    gctINT numEntries = 0;
+     gctUINT32_PTR pageTable;
+     gctBOOL acquired = gcvFALSE;
+ 
+-    /* find the start of dynamic address space. */
+-    for (i = 0; i < gcdMMU_MTLB_ENTRY_NUM; i++)
++    /* Find all the dynamic address space. */
++    gcmkONERROR(_FindDynamicSpace(Mmu, &nodeArray, &nodeArraySize));
++
++    /* TODO: We only use the largest one for now. */
++    for (i = 0; i < nodeArraySize; i++)
+     {
+-        if (!Mmu->mtlbLogical[i])
++        if (nodeArray[i].entries > numEntries)
+         {
+-            break;
++            Mmu->dynamicMappingStart = nodeArray[i].start;
++            numEntries               = nodeArray[i].entries;
+         }
+     }
+ 
+-    Mmu->dynamicMappingStart = i;
+-
+-    /* Number of entries in Master TLB for dynamic mapping. */
+-    numEntries = gcdMMU_MTLB_ENTRY_NUM - i;
++    gckOS_Free(Mmu->os, (gctPOINTER)nodeArray);
+ 
+     Mmu->pageTableSize = numEntries * 4096;
+ 
+@@ -545,7 +640,9 @@ _SetupDynamicSpace(
+     acquired = gcvTRUE;
+ 
+     /* Map to Master TLB. */
+-    for (; i < gcdMMU_MTLB_ENTRY_NUM; i++)
++    for (i = (gctINT)Mmu->dynamicMappingStart;
++         i < (gctINT)Mmu->dynamicMappingStart + numEntries;
++         i++)
+     {
+         _WritePageEntry(Mmu->mtlbLogical + i,
+                         physical
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
+index 8a442a2..8b8bbdc 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
++++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
+@@ -2144,6 +2144,9 @@ gckVIDMEM_Unlock(
+ 
+             if (!Node->Virtual.contiguous
+             &&  (Node->Virtual.lockeds[Kernel->core] == 1)
++#if gcdENABLE_VG
++            && (Kernel->vg == gcvNULL)
++#endif
+             )
+             {
+                 if (Type == gcvSURF_BITMAP)
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
+index 7077412..4406d7e 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
++++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
+@@ -2072,6 +2072,12 @@ gckHARDWARE_QueryPowerManagementState(
+     OUT gceCHIPPOWERSTATE* State
+     );
+ 
++gceSTATUS
++gckHARDWARE_SetPowerManagement(
++    IN gckHARDWARE Hardware,
++    IN gctBOOL PowerManagement
++    );
++
+ #if gcdENABLE_FSCALE_VAL_ADJUST
+ gceSTATUS
+ gckHARDWARE_SetFscaleValue(
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
+index ac86399..44689b0 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
++++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
+@@ -74,7 +74,6 @@ typedef struct _gcsSYNC_CONTEXT  *      gcsSYNC_CONTEXT_PTR;
+ /******************************************************************************\
+ ******************************* Process local storage *************************
+ \******************************************************************************/
+-
+ typedef struct _gcsPLS * gcsPLS_PTR;
+ typedef struct _gcsPLS
+ {
+@@ -107,6 +106,7 @@ typedef struct _gcsPLS
+ 
+     /* Reference count for destructor. */
+     gcsATOM_PTR                 reference;
++    gctBOOL                     bKFS;
+ #if gcdUSE_NPOT_PATCH
+     gctBOOL                     bNeedSupportNP2Texture;
+ #endif
+@@ -123,7 +123,7 @@ extern gcsPLS gcPLS;
+ typedef struct _gcsTLS * gcsTLS_PTR;
+ 
+ typedef void (* gctTLS_DESTRUCTOR) (
+-    gcsTLS_PTR TLS
++    gcsTLS_PTR
+     );
+ 
+ typedef struct _gcsTLS
+@@ -658,8 +658,6 @@ gcoHAL_QueryChipFeature(
+     IN gceFEATURE   Feature);
+ 
+ #endif
+-
+-
+ /******************************************************************************\
+ ********************************** gcoOS Object *********************************
+ \******************************************************************************/
+@@ -1775,20 +1773,6 @@ gcoSURF_QueryVidMemNode(
+     OUT gctUINT_PTR Bytes
+     );
+ 
+-/*  Set usage attribute of a surface. */
+-gceSTATUS
+-gcoSURF_SetUsage(
+-    IN gcoSURF Surface,
+-    IN gceSURF_USAGE Usage
+-    );
+-
+-/*  Return usage attribute of a surface. */
+-gceSTATUS
+-gcoSURF_QueryUsage(
+-    IN gcoSURF Surface,
+-    OUT gceSURF_USAGE *Usage
+-    );
+-
+ /* Set the color type of the surface. */
+ gceSTATUS
+ gcoSURF_SetColorType(
+@@ -1975,6 +1959,14 @@ gcoSURF_SetWindow(
+     IN gctUINT Height
+     );
+ 
++/* Set width/height alignment of the surface directly and calculate stride/size. This is only for dri backend now. Please be careful before use. */
++gceSTATUS
++gcoSURF_SetAlignment(
++    IN gcoSURF Surface,
++    IN gctUINT Width,
++    IN gctUINT Height
++    );
++
+ /* Increase reference count of the surface. */
+ gceSTATUS
+ gcoSURF_ReferenceSurface(
+@@ -2009,6 +2001,12 @@ gcoSURF_SetOffset(
+     );
+ 
+ gceSTATUS
++gcoSURF_GetOffset(
++    IN gcoSURF Surface,
++    OUT gctUINT *Offset
++    );
++
++gceSTATUS
+ gcoSURF_NODE_Cache(
+     IN gcsSURF_NODE_PTR Node,
+     IN gctPOINTER Logical,
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h
+index 4a0870f..8693c37 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h
++++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h
+@@ -36,12 +36,16 @@ extern "C" {
+ #endif
+ 
+ #ifndef GC_ENABLE_LOADTIME_OPT
+-#define GC_ENABLE_LOADTIME_OPT      1
++#define GC_ENABLE_LOADTIME_OPT           1
+ #endif
+ 
+ #define TEMP_OPT_CONSTANT_TEXLD_COORD    1
+ 
+-#define TEMP_SHADER_PATCH            1
++#define TEMP_SHADER_PATCH                1
++
++#define ADD_PRE_ROTATION_TO_VS           0
++
++#define TEMP_INLINE_ALL_EXPANSION            1
+ /******************************* IR VERSION ******************/
+ #define gcdSL_IR_VERSION gcmCC('\0','\0','\0','\1')
+ 
+@@ -683,6 +687,13 @@ typedef enum _gceSHADER_FLAGS
+     gcvSHADER_USE_ALPHA_KILL            = 0x100,
+ #endif
+ 
++#if ADD_PRE_ROTATION_TO_VS
++    gcvSHADER_VS_PRE_ROTATION           = 0x200,
++#endif
++
++#if TEMP_INLINE_ALL_EXPANSION
++    gcvSHADER_INLINE_ALL_EXPANSION      = 0x200,
++#endif
+ }
+ gceSHADER_FLAGS;
+ 
+@@ -771,10 +782,15 @@ typedef enum _gceSHADER_OPTIMIZATION
+     /* optimize varying packing */
+     gcvOPTIMIZATION_VARYINGPACKING              = 1 << 22,
+ 
++#if TEMP_INLINE_ALL_EXPANSION
++	gcvOPTIMIZATION_INLINE_ALL_EXPANSION        = 1 << 23,
++#endif
++
+     /*  Full optimization. */
+     /*  Note that gcvOPTIMIZATION_LOAD_SW_WORKAROUND is off. */
+ 	gcvOPTIMIZATION_FULL                        = 0x7FFFFFFF &
+                                                   ~gcvOPTIMIZATION_LOAD_SW_WORKAROUND &
++                                                  ~gcvOPTIMIZATION_INLINE_ALL_EXPANSION &
+                                                   ~gcvOPTIMIZATION_POWER_OPTIMIZATION,
+ 
+ 	/* Optimization Unit Test flag. */
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h
+index 028bbd1..b056c52 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h
++++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h
+@@ -210,6 +210,9 @@ typedef struct _gcsHAL_QUERY_CHIP_IDENTITY
+     /* Supported minor feature 3 fields. */
+     gctUINT32                   chipMinorFeatures3;
+ 
++    /* Supported minor feature 4 fields. */
++    gctUINT32                   chipMinorFeatures4;
++
+     /* Number of streams supported. */
+     gctUINT32                   streamCount;
+ 
+@@ -929,30 +932,30 @@ typedef struct _gcsHAL_INTERFACE
+ 
+         struct _gcsHAL_GET_SHARED_INFO
+         {
++            /* Process id. */
+             IN gctUINT32            pid;
++
++            /* Data id. */
+             IN gctUINT32            dataId;
+-            /* gcuVIDMEM_NODE_PTR */
+-            IN gctUINT64            node;
+-            /* gctUINT8_PTR */
+-            OUT gctUINT64           data;
+-            /* fix size. gctUINT8_PTR*/
+-            OUT gctUINT64           nodeData;
+-            gctUINT64               size;
+-            IN gceVIDMEM_NODE_SHARED_INFO_TYPE infoType;
++
++            /* Data size. */
++            IN gctSIZE_T            bytes;
++
++            /* Pointer to save the shared data. */
++            OUT gctPOINTER          data;
+         }
+         GetSharedInfo;
+ 
+         struct _gcsHAL_SET_SHARED_INFO
+         {
++            /* Data id. */
+             IN gctUINT32            dataId;
+-            /* gcuVIDMEM_NODE_PTR */
+-            IN gctUINT64   node;
+-            /* gctUINT8_PTR */
+-            IN gctUINT64         data;
+-            /* gctUINT8_PTR */
+-            IN gctUINT64         nodeData;
+-            IN gctUINT64            size;
+-            IN gceVIDMEM_NODE_SHARED_INFO_TYPE infoType;
++
++            /* Data to be shared. */
++            IN gctPOINTER           data;
++
++            /* Data size. */
++            IN gctSIZE_T            bytes;
+         }
+         SetSharedInfo;
+ 
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
+index 249b61b..8481375 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
++++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
+@@ -323,50 +323,6 @@ gcoSURF_Resolve(
+     IN gcoSURF DestSurface
+     );
+ 
+-/* Export the render target. */
+-gceSTATUS
+-gcoSURF_ExportRenderTarget(
+-    IN gcoSURF SrcSurface
+-);
+-
+-/* Import the render target. */
+-gceSTATUS
+-gcoSURF_ImportRenderTarget(
+-    IN gctUINT32 Pid,
+-    IN gcoSURF SrcSurface
+-);
+-
+-/* Save the Resolve info to kernel. */
+-gceSTATUS
+-gcoSURF_PrepareRemoteResolveRect(
+-    IN gcoSURF SrcSurface,
+-    IN gcsPOINT_PTR SrcOrigin,
+-    IN gcsPOINT_PTR DestOrigin,
+-    IN gcsPOINT_PTR RectSize
+-    );
+-
+-/* Resolve using the rectangle info previously saved in the vid mem node. */
+-gceSTATUS
+-gcoSURF_ResolveFromStoredRect(
+-    IN gcoSURF SrcSurface,
+-    IN gcoSURF DestSurface
+-    );
+-
+-/* Using the info that Process Pid saved to do resolve. */
+-gceSTATUS
+-gcoSURF_RemoteResolveRect(
+-    IN gcoSURF SrcSurface,
+-    IN gcoSURF DestSurface,
+-    IN gctBOOL *resolveDiscarded
+-    );
+-
+-/* Return the "resolve submitted indicator" signal. */
+-gceSTATUS
+-gcoSURF_GetRTSignal(
+-    IN gcoSURF RTSurface,
+-    OUT gctSIGNAL * resolveSubmittedSignal
+-    );
+-
+ /* Resolve rectangular area of a surface. */
+ gceSTATUS
+ gcoSURF_ResolveRect(
+@@ -1684,6 +1640,12 @@ gcoTEXTURE_IsRenderable(
+     );
+ 
+ gceSTATUS
++gcoTEXTURE_IsRenderableEx(
++    IN gcoTEXTURE Texture,
++    IN gctUINT Level
++    );
++
++gceSTATUS
+ gcoTEXTURE_IsComplete(
+     IN gcoTEXTURE Texture,
+     IN gctINT MaxLevel
+@@ -2028,21 +1990,15 @@ gceSTATUS
+ gcoHAL_GetSharedInfo(
+     IN gctUINT32 Pid,
+     IN gctUINT32 DataId,
+-    OUT gctUINT8_PTR Data,
+     IN gctSIZE_T Bytes,
+-    IN gctUINT64 Node,
+-    OUT gctUINT8_PTR NodeData,
+-    IN gceVIDMEM_NODE_SHARED_INFO_TYPE SharedInfoType
++    OUT gctPOINTER Data
+     );
+ 
+ gceSTATUS
+ gcoHAL_SetSharedInfo(
+     IN gctUINT32 DataId,
+-    IN gctUINT8_PTR Data,
+-    IN gctSIZE_T Bytes,
+-    IN gctUINT64 Node,
+-    IN gctUINT8_PTR NodeData,
+-    IN gceVIDMEM_NODE_SHARED_INFO_TYPE SharedInfoType
++    IN gctPOINTER Data,
++    IN gctSIZE_T Bytes
+     );
+ 
+ #ifdef __cplusplus
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h
+index cf6b425..a1d9ae5 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h
++++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h
+@@ -181,13 +181,6 @@ typedef enum _gceCACHEOPERATION
+ }
+ gceCACHEOPERATION;
+ 
+-typedef enum _gceVIDMEM_NODE_SHARED_INFO_TYPE
+-{
+-    gcvVIDMEM_INFO_GENERIC,
+-    gcvVIDMEM_INFO_DIRTY_RECTANGLE
+-}
+-gceVIDMEM_NODE_SHARED_INFO_TYPE;
+-
+ /* Surface types. */
+ typedef enum _gceSURF_TYPE
+ {
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
+index afe83d0..9e2a8db 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
++++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
+@@ -391,15 +391,6 @@
+ #endif
+ 
+ /*
+-    gcdPOWER_MANAGEMENT
+-
+-        This define enables the power management code.
+-*/
+-#ifndef gcdPOWER_MANAGEMENT
+-#   define gcdPOWER_MANAGEMENT                  1
+-#endif
+-
+-/*
+     gcdPOWER_SUSNPEND_WHEN_IDLE
+ 
+         Set to 1 to make GPU enter gcvPOWER_SUSPEND when idle detected,
+@@ -428,7 +419,7 @@
+         If the value is 0, no timeout will be checked for.
+ */
+ #ifndef gcdGPU_TIMEOUT
+-#   if gcdFPGA_BUILD
++#if gcdFPGA_BUILD
+ #       define gcdGPU_TIMEOUT                   0
+ #   else
+ #       define gcdGPU_TIMEOUT                   20000
+@@ -726,31 +717,13 @@
+ 
+         Support swap with a specific rectangle.
+ 
+-        Set the rectangle with eglSetSwapRectangleANDROID api.
++        Set the rectangle with eglSetSwapRectangleVIV api.
+ */
+ #ifndef gcdSUPPORT_SWAP_RECTANGLE
+ #   define gcdSUPPORT_SWAP_RECTANGLE            0
+ #endif
+ 
+ /*
+-    gcdDEFER_RESOLVES
+-
+-        Support deferred resolves for 3D apps.
+-*/
+-#ifndef gcdDEFER_RESOLVES
+-#   define gcdDEFER_RESOLVES                    0
+-#endif
+-
+-/*
+-    gcdCOPYBLT_OPTIMIZATION
+-
+-        Combine dirty areas resulting from Android's copyBlt.
+-*/
+-#ifndef gcdCOPYBLT_OPTIMIZATION
+-#   define gcdCOPYBLT_OPTIMIZATION              0
+-#endif
+-
+-/*
+     gcdGPU_LINEAR_BUFFER_ENABLED
+ 
+         Use linear buffer for GPU apps so HWC can do 2D composition.
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
+index 808fde0..03cb4d6 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
++++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
+@@ -28,7 +28,7 @@
+ 
+ #define gcvVERSION_PATCH        9
+ 
+-#define gcvVERSION_BUILD     4651
++#define gcvVERSION_BUILD     6622
+ 
+ #define gcvVERSION_DATE      __DATE__
+ 
+diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h
+index 5ff0281..2a910e8 100644
+--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h
++++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h
+@@ -552,6 +552,12 @@ gckVGHARDWARE_QueryPowerManagementState(
+     );
+ 
+ gceSTATUS
++gckVGHARDWARE_SetPowerManagement(
++    IN gckVGHARDWARE Hardware,
++    IN gctBOOL PowerManagement
++    );
++
++gceSTATUS
+ gckVGHARDWARE_SetPowerOffTimeout(
+     IN gckVGHARDWARE  Hardware,
+     IN gctUINT32    Timeout
+diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
+index 7168f0e..168987a 100644
+--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
++++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
+@@ -304,6 +304,7 @@ gckGALDEVICE_Construct(
+     IN gctINT Signal,
+     IN gctUINT LogFileSize,
+     IN struct device *pdev,
++    IN gctINT PowerManagement,
+     OUT gckGALDEVICE *Device
+     )
+ {
+@@ -538,6 +539,9 @@ gckGALDEVICE_Construct(
+             device->kernels[gcvCORE_MAJOR]->hardware, FastClear, Compression
+             ));
+ 
++        gcmkONERROR(gckHARDWARE_SetPowerManagement(
++            device->kernels[gcvCORE_MAJOR]->hardware, PowerManagement
++            ));
+ 
+ #if COMMAND_PROCESSOR_VERSION == 1
+         /* Start the command queue. */
+@@ -593,6 +597,10 @@ gckGALDEVICE_Construct(
+             device
+             ));
+ 
++        gcmkONERROR(gckHARDWARE_SetPowerManagement(
++            device->kernels[gcvCORE_2D]->hardware, PowerManagement
++            ));
++
+ #if COMMAND_PROCESSOR_VERSION == 1
+         /* Start the command queue. */
+         gcmkONERROR(gckCOMMAND_Start(device->kernels[gcvCORE_2D]->command));
+@@ -624,6 +632,11 @@ gckGALDEVICE_Construct(
+             device->coreMapping[gcvHARDWARE_VG] = gcvCORE_VG;
+         }
+ 
++
++        gcmkONERROR(gckVGHARDWARE_SetPowerManagement(
++            device->kernels[gcvCORE_VG]->vg->hardware,
++            PowerManagement
++            ));
+ #endif
+     }
+     else
+diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
+index 460f022..d488fc8 100644
+--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
++++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
+@@ -169,6 +169,7 @@ gceSTATUS gckGALDEVICE_Construct(
+     IN gctINT Signal,
+     IN gctUINT LogFileSize,
+     IN struct device *pdev,
++    IN gctINT PowerManagement,
+     OUT gckGALDEVICE *Device
+     );
+ 
+diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
+index 64cace1..183000d 100644
+--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
++++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
+@@ -131,6 +131,9 @@ module_param(fastClear, int, 0644);
+ static int compression = -1;
+ module_param(compression, int, 0644);
+ 
++static int powerManagement = 1;
++module_param(powerManagement, int, 0644);
++
+ static int signal = 48;
+ module_param(signal, int, 0644);
+ 
+@@ -781,6 +784,9 @@ static int drv_init(struct device *pdev)
+     }
+ #endif
+ 
++    printk(KERN_INFO "Galcore version %d.%d.%d.%d\n",
++        gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, gcvVERSION_BUILD);
++
+     if (showArgs)
+     {
+         printk("galcore options:\n");
+@@ -810,7 +816,8 @@ static int drv_init(struct device *pdev)
+         printk("  signal            = %d\n",      signal);
+         printk("  baseAddress       = 0x%08lX\n", baseAddress);
+         printk("  physSize          = 0x%08lX\n", physSize);
+-	printk(" logFileSize         = %d KB \n",     logFileSize);
++        printk("  logFileSize       = %d KB \n",  logFileSize);
++        printk("  powerManagement   = %d\n",      powerManagement);
+ #if ENABLE_GPU_CLOCK_BY_DRIVER
+         printk("  coreClock       = %lu\n",     coreClock);
+ #endif
+@@ -833,6 +840,7 @@ static int drv_init(struct device *pdev)
+         bankSize, fastClear, compression, baseAddress, physSize, signal,
+         logFileSize,
+         pdev,
++        powerManagement,
+         &device
+         ));
+ 
+diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
+index dfbc699..6a0295d 100644
+--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
++++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
+@@ -55,6 +55,7 @@ const char * _PLATFORM = "\n\0$PLATFORM$Linux$\n";
+ #endif
+ 
+ #define USER_SIGNAL_TABLE_LEN_INIT  64
++#define gcdSUPPRESS_OOM_MESSAGE 1
+ 
+ #define MEMORY_LOCK(os) \
+     gcmkVERIFY_OK(gckOS_AcquireMutex( \
+@@ -85,6 +86,12 @@ const char * _PLATFORM = "\n\0$PLATFORM$Linux$\n";
+ #define gcmkNONPAGED_MEMROY_PROT(x) pgprot_noncached(x)
+ #endif
+ 
++#if gcdSUPPRESS_OOM_MESSAGE
++#define gcdNOWARN __GFP_NOWARN
++#else
++#define gcdNOWARN 0
++#endif
++
+ #define gcdINFINITE_TIMEOUT     (60 * 1000)
+ #define gcdDETECT_TIMEOUT       0
+ #define gcdDETECT_DMA_ADDRESS   1
+@@ -261,7 +268,7 @@ _CreateMdl(
+ 
+     gcmkHEADER_ARG("ProcessID=%d", ProcessID);
+ 
+-    mdl = (PLINUX_MDL)kzalloc(sizeof(struct _LINUX_MDL), GFP_KERNEL | __GFP_NOWARN);
++    mdl = (PLINUX_MDL)kzalloc(sizeof(struct _LINUX_MDL), GFP_KERNEL | gcdNOWARN);
+     if (mdl == gcvNULL)
+     {
+         gcmkFOOTER_NO();
+@@ -322,7 +329,7 @@ _CreateMdlMap(
+ 
+     gcmkHEADER_ARG("Mdl=0x%X ProcessID=%d", Mdl, ProcessID);
+ 
+-    mdlMap = (PLINUX_MDL_MAP)kmalloc(sizeof(struct _LINUX_MDL_MAP), GFP_KERNEL | __GFP_NOWARN);
++    mdlMap = (PLINUX_MDL_MAP)kmalloc(sizeof(struct _LINUX_MDL_MAP), GFP_KERNEL | gcdNOWARN);
+     if (mdlMap == gcvNULL)
+     {
+         gcmkFOOTER_NO();
+@@ -481,7 +488,7 @@ _NonContiguousAlloc(
+ 
+     size = NumPages * sizeof(struct page *);
+ 
+-    pages = kmalloc(size, GFP_KERNEL | __GFP_NOWARN);
++    pages = kmalloc(size, GFP_KERNEL | gcdNOWARN);
+ 
+     if (!pages)
+     {
+@@ -496,7 +503,7 @@ _NonContiguousAlloc(
+ 
+     for (i = 0; i < NumPages; i++)
+     {
+-        p = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_NOWARN);
++        p = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN);
+ 
+         if (!p)
+         {
+@@ -762,7 +769,7 @@ _AllocateIntegerId(
+     int result;
+ 
+ again:
+-    if (idr_pre_get(&Database->idr, GFP_KERNEL | __GFP_NOWARN) == 0)
++    if (idr_pre_get(&Database->idr, GFP_KERNEL | gcdNOWARN) == 0)
+     {
+         return gcvSTATUS_OUT_OF_MEMORY;
+     }
+@@ -954,7 +961,7 @@ gckOS_Construct(
+     gcmkVERIFY_ARGUMENT(Os != gcvNULL);
+ 
+     /* Allocate the gckOS object. */
+-    os = (gckOS) kmalloc(gcmSIZEOF(struct _gckOS), GFP_KERNEL | __GFP_NOWARN);
++    os = (gckOS) kmalloc(gcmSIZEOF(struct _gckOS), GFP_KERNEL | gcdNOWARN);
+ 
+     if (os == gcvNULL)
+     {
+@@ -1171,7 +1178,7 @@ _CreateKernelVirtualMapping(
+ 
+     if (Mdl->contiguous)
+     {
+-        pages = kmalloc(sizeof(struct page *) * numPages, GFP_KERNEL | __GFP_NOWARN);
++        pages = kmalloc(sizeof(struct page *) * numPages, GFP_KERNEL | gcdNOWARN);
+ 
+         if (!pages)
+         {
+@@ -1385,7 +1392,7 @@ gckOS_AllocateMemory(
+     }
+     else
+     {
+-        memory = (gctPOINTER) kmalloc(Bytes, GFP_KERNEL | __GFP_NOWARN);
++        memory = (gctPOINTER) kmalloc(Bytes, GFP_KERNEL | gcdNOWARN);
+     }
+ 
+     if (memory == gcvNULL)
+@@ -1904,7 +1911,7 @@ gckOS_AllocateNonPagedMemory(
+         addr = dma_alloc_coherent(gcvNULL,
+                 mdl->numPages * PAGE_SIZE,
+                 &mdl->dmaHandle,
+-                GFP_KERNEL | __GFP_NOWARN);
++                GFP_KERNEL | gcdNOWARN);
+     }
+ #else
+     size    = mdl->numPages * PAGE_SIZE;
+@@ -1915,7 +1922,7 @@ gckOS_AllocateNonPagedMemory(
+     if (page == gcvNULL)
+ #endif
+     {
+-        page = alloc_pages(GFP_KERNEL | __GFP_NOWARN, order);
++        page = alloc_pages(GFP_KERNEL | gcdNOWARN, order);
+     }
+ 
+     if (page == gcvNULL)
+@@ -3848,6 +3855,9 @@ gckOS_AllocatePagedMemoryEx(
+     gctSIZE_T bytes;
+     gctBOOL locked = gcvFALSE;
+     gceSTATUS status;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
++    gctPOINTER addr = gcvNULL;
++#endif
+ 
+     gcmkHEADER_ARG("Os=0x%X Contiguous=%d Bytes=%lu", Os, Contiguous, Bytes);
+ 
+@@ -3873,13 +3883,27 @@ gckOS_AllocatePagedMemoryEx(
+     {
+         /* Get contiguous pages, and suppress warning (stack dump) from kernel when
+            we run out of memory. */
+-        mdl->u.contiguousPages =
+-            alloc_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY, GetOrder(numPages));
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
++        addr =
++            alloc_pages_exact(numPages * PAGE_SIZE, GFP_KERNEL | gcdNOWARN | __GFP_NORETRY);
+ 
++        mdl->u.contiguousPages = addr
++                               ? virt_to_page(addr)
++                               : gcvNULL;
++
++        mdl->exact = gcvTRUE;
++#else
++        mdl->u.contiguousPages =
++            alloc_pages(GFP_KERNEL | gcdNOWARN | __GFP_NORETRY, GetOrder(numPages));
++#endif
+         if (mdl->u.contiguousPages == gcvNULL)
+         {
+             mdl->u.contiguousPages =
+-                alloc_pages(GFP_KERNEL | __GFP_HIGHMEM | __GFP_NOWARN, GetOrder(numPages));
++                alloc_pages(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN, GetOrder(numPages));
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
++            mdl->exact = gcvFALSE;
++#endif
+         }
+     }
+     else
+@@ -4024,7 +4048,16 @@ gckOS_FreePagedMemory(
+ 
+     if (mdl->contiguous)
+     {
+-        __free_pages(mdl->u.contiguousPages, GetOrder(mdl->numPages));
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
++        if (mdl->exact == gcvTRUE)
++        {
++            free_pages_exact(page_address(mdl->u.contiguousPages), mdl->numPages * PAGE_SIZE);
++        }
++        else
++#endif
++        {
++            __free_pages(mdl->u.contiguousPages, GetOrder(mdl->numPages));
++        }
+     }
+     else
+     {
+@@ -4859,7 +4892,7 @@ gckOS_MapUserPointer(
+     gcmkVERIFY_ARGUMENT(Size > 0);
+     gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
+ 
+-    buf = kmalloc(Size, GFP_KERNEL | __GFP_NOWARN);
++    buf = kmalloc(Size, GFP_KERNEL | gcdNOWARN);
+     if (buf == gcvNULL)
+     {
+         gcmkTRACE(
+@@ -5274,7 +5307,7 @@ OnError:
+         MEMORY_MAP_LOCK(Os);
+ 
+         /* Allocate the Info struct. */
+-        info = (gcsPageInfo_PTR)kmalloc(sizeof(gcsPageInfo), GFP_KERNEL | __GFP_NOWARN);
++        info = (gcsPageInfo_PTR)kmalloc(sizeof(gcsPageInfo), GFP_KERNEL | gcdNOWARN);
+ 
+         if (info == gcvNULL)
+         {
+@@ -5283,7 +5316,7 @@ OnError:
+         }
+ 
+         /* Allocate the array of page addresses. */
+-        pages = (struct page **)kmalloc(pageCount * sizeof(struct page *), GFP_KERNEL | __GFP_NOWARN);
++        pages = (struct page **)kmalloc(pageCount * sizeof(struct page *), GFP_KERNEL | gcdNOWARN);
+ 
+         if (pages == gcvNULL)
+         {
+@@ -6502,7 +6535,7 @@ gckOS_CreateSemaphore(
+     gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
+ 
+     /* Allocate the semaphore structure. */
+-    sem = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL | __GFP_NOWARN);
++    sem = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL | gcdNOWARN);
+     if (sem == gcvNULL)
+     {
+         gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+@@ -6942,6 +6975,7 @@ gckOS_SetGPUPower(
+ #else
+     		imx_gpc_power_up_pu(false);
+ #endif
++
+ 	}
+     /* TODO: Put your code here. */
+     gcmkFOOTER_NO();
+@@ -7255,7 +7289,7 @@ gckOS_CreateSignal(
+     gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
+ 
+     /* Create an event structure. */
+-    signal = (gcsSIGNAL_PTR) kmalloc(sizeof(gcsSIGNAL), GFP_KERNEL | __GFP_NOWARN);
++    signal = (gcsSIGNAL_PTR) kmalloc(sizeof(gcsSIGNAL), GFP_KERNEL | gcdNOWARN);
+ 
+     if (signal == gcvNULL)
+     {
+@@ -8000,7 +8034,7 @@ gckOS_CreateSemaphoreVG(
+     do
+     {
+         /* Allocate the semaphore structure. */
+-    	newSemaphore = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL | __GFP_NOWARN);
++    	newSemaphore = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL | gcdNOWARN);
+     	if (newSemaphore == gcvNULL)
+     	{
+         	gcmkERR_BREAK(gcvSTATUS_OUT_OF_MEMORY);
+diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h
+index e970477..006632c 100644
+--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h
++++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h
+@@ -54,6 +54,9 @@ typedef struct _LINUX_MDL
+     gctINT                  numPages;
+     gctINT                  pagedMem;
+     gctBOOL                 contiguous;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
++    gctBOOL                 exact;
++#endif
+     dma_addr_t              dmaHandle;
+     PLINUX_MDL_MAP          maps;
+     struct _LINUX_MDL *     prev;
+-- 
+1.8.3.2
+
diff --git a/recipes-kernel/linux/linux-boundary-3.0.35/0005-ENGR00264275-GPU-Correct-suspend-resume-calling-afte.patch b/recipes-kernel/linux/linux-boundary-3.0.35/0005-ENGR00264275-GPU-Correct-suspend-resume-calling-afte.patch
new file mode 100644
index 0000000..fa937e4
--- /dev/null
+++ b/recipes-kernel/linux/linux-boundary-3.0.35/0005-ENGR00264275-GPU-Correct-suspend-resume-calling-afte.patch
@@ -0,0 +1,61 @@ 
+From a845abe4589366d3e37b5a646be6337984074b28 Mon Sep 17 00:00:00 2001
+From: Loren HUANG <b02279@freescale.com>
+Date: Wed, 22 May 2013 17:21:30 +0800
+Subject: [PATCH 5/6] ENGR00264275 [GPU]Correct suspend/resume calling after
+ adding runtime pm.
+
+After enabling runtime pm the suspend/resume entry is changed.
+
+-Add new entry for suspend/resume in runtime pm frame work.
+-Add static define for all runtime pm function.
+
+Upstream-Status: Backport [3.5.7-1.0.0]
+
+Signed-off-by: Loren HUANG <b02279@freescale.com>
+Acked-by: Lily Zhang
+---
+ .../gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c   | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
+index 183000d..3632a6c 100644
+--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
++++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
+@@ -1252,20 +1252,32 @@ static const struct of_device_id mxs_gpu_dt_ids[] = {
+ MODULE_DEVICE_TABLE(of, mxs_gpu_dt_ids);
+ 
+ #ifdef CONFIG_PM
+-int gpu_runtime_suspend(struct device *dev)
++static int gpu_runtime_suspend(struct device *dev)
+ {
+ 	release_bus_freq(BUS_FREQ_HIGH);
+ 	return 0;
+ }
+ 
+-int gpu_runtime_resume(struct device *dev)
++static int gpu_runtime_resume(struct device *dev)
+ {
+ 	request_bus_freq(BUS_FREQ_HIGH);
+ 	return 0;
+ }
+ 
++static int gpu_system_suspend(struct device *dev)
++{
++	pm_message_t state={0};
++	return gpu_suspend(to_platform_device(dev), state);
++}
++
++static int gpu_system_resume(struct device *dev)
++{
++	return gpu_resume(to_platform_device(dev));
++}
++
+ static const struct dev_pm_ops gpu_pm_ops = {
+ 	SET_RUNTIME_PM_OPS(gpu_runtime_suspend, gpu_runtime_resume, NULL)
++	SET_SYSTEM_SLEEP_PM_OPS(gpu_system_suspend, gpu_system_resume)
+ };
+ #endif
+ #endif
+-- 
+1.8.3.2
+
diff --git a/recipes-kernel/linux/linux-boundary-3.0.35/0006-ENGR00265130-gpu-Correct-section-mismatch-in-gpu-ker.patch b/recipes-kernel/linux/linux-boundary-3.0.35/0006-ENGR00265130-gpu-Correct-section-mismatch-in-gpu-ker.patch
new file mode 100644
index 0000000..43407a1
--- /dev/null
+++ b/recipes-kernel/linux/linux-boundary-3.0.35/0006-ENGR00265130-gpu-Correct-section-mismatch-in-gpu-ker.patch
@@ -0,0 +1,60 @@ 
+From 376d63e9b981118f83646a836ce6626e541de1a3 Mon Sep 17 00:00:00 2001
+From: Loren HUANG <b02279@freescale.com>
+Date: Fri, 31 May 2013 18:29:58 +0800
+Subject: [PATCH 6/6] ENGR00265130 gpu:Correct section mismatch in gpu kernel
+ driver
+
+-Remove the __devinit for suspend/resume function.
+-Replace __devinit to __devexit for remove function.
+
+Upstream-Status: Backport [3.5.7-1.0.0]
+
+Signed-off-by: Loren HUANG <b02279@freescale.com>
+Acked-by: Lily Zhang
+---
+ drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
+index 3632a6c..9d9dc57 100644
+--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
++++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
+@@ -1111,7 +1111,7 @@ static int __devinit gpu_probe(struct platform_device *pdev)
+     return ret;
+ }
+ 
+-static int __devinit gpu_remove(struct platform_device *pdev)
++static int __devexit gpu_remove(struct platform_device *pdev)
+ {
+     gcmkHEADER();
+ #if gcdENABLE_FSCALE_VAL_ADJUST
+@@ -1123,7 +1123,7 @@ static int __devinit gpu_remove(struct platform_device *pdev)
+     return 0;
+ }
+ 
+-static int __devinit gpu_suspend(struct platform_device *dev, pm_message_t state)
++static int gpu_suspend(struct platform_device *dev, pm_message_t state)
+ {
+     gceSTATUS status;
+     gckGALDEVICE device;
+@@ -1173,7 +1173,7 @@ static int __devinit gpu_suspend(struct platform_device *dev, pm_message_t state
+     return 0;
+ }
+ 
+-static int __devinit gpu_resume(struct platform_device *dev)
++static int gpu_resume(struct platform_device *dev)
+ {
+     gceSTATUS status;
+     gckGALDEVICE device;
+@@ -1284,7 +1284,7 @@ static const struct dev_pm_ops gpu_pm_ops = {
+ 
+ static struct platform_driver gpu_driver = {
+     .probe      = gpu_probe,
+-    .remove     = gpu_remove,
++    .remove     = __devexit_p(gpu_remove),
+ 
+     .suspend    = gpu_suspend,
+     .resume     = gpu_resume,
+-- 
+1.8.3.2
+
diff --git a/recipes-kernel/linux/linux-boundary_3.0.35.bb b/recipes-kernel/linux/linux-boundary_3.0.35.bb
index abf8afd..572de6f 100644
--- a/recipes-kernel/linux/linux-boundary_3.0.35.bb
+++ b/recipes-kernel/linux/linux-boundary_3.0.35.bb
@@ -8,7 +8,15 @@  DESCRIPTION = "Linux kernel for Boundary Devices boards"
 SRC_URI = "git://github.com/boundarydevices/linux-imx6.git \
            file://defconfig"
 
-LOCALVERSION = "-4.0.0"
+LOCALVERSION = "-4.0.0+yocto"
 SRCREV = "7d8752905c118af9063738a533227de0b2f6ecd4"
 
+# GPU support patches
+SRC_URI += "file://0001-ENGR00255688-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch \
+            file://0002-ENGR00265465-gpu-Add-global-value-for-minimum-3D-clo.patch \
+            file://0003-ENGR00261814-4-gpu-use-new-PU-power-on-off-interface.patch \
+            file://0004-ENGR00264288-1-GPU-Integrate-4.6.9p12-release-kernel.patch \
+            file://0005-ENGR00264275-GPU-Correct-suspend-resume-calling-afte.patch \
+            file://0006-ENGR00265130-gpu-Correct-section-mismatch-in-gpu-ker.patch"
+
 COMPATIBLE_MACHINE = "(mx6)"