diff mbox

[RFC] ARM: OMAP3: Add device tree and pdata hooks to enable SGX on OMAP3

Message ID 1472844308-10331-1-git-send-email-aford173@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Adam Ford Sept. 2, 2016, 7:25 p.m. UTC
From: Adam Ford <aford173@gmail.com>

Sorry about the wordy email.

The reset controller stuff needs an overhaul, but this is an attempt
to allow the last revision of the SGX driver to work with a modern kernel.

Unfortunately, I get an error when I build the SGX driver:

pvrsrvkm pvrsrvkm: SGX Platform data missing deassert_reset!

So it's obviously missing something.  If someone can point me in
the righ direction. I need to deassert that by writing to a register
but I am not sure exactly how to go about that.

On the DM3730 I am using it appears to be RM_RSTST_SGX but this is
is inconsistent with the SGX notes in section 8.2.1.2 of the DM3730
TRM.

I want to make sure the SGX_FCLK is properly set to which I beleive
shoudld 192MHz, but I am not sure which macros are the proper ones.

Comments

Adam Ford Sept. 2, 2016, 8:22 p.m. UTC | #1
On Fri, Sep 2, 2016 at 2:25 PM,  <aford173@gmail.com> wrote:
> From: Adam Ford <aford173@gmail.com>
>
> Sorry about the wordy email.
>
> The reset controller stuff needs an overhaul, but this is an attempt
> to allow the last revision of the SGX driver to work with a modern kernel.
>
> Unfortunately, I get an error when I build the SGX driver:
>
> pvrsrvkm pvrsrvkm: SGX Platform data missing deassert_reset!
>
> So it's obviously missing something.  If someone can point me in
> the righ direction. I need to deassert that by writing to a register
> but I am not sure exactly how to go about that.
>
> On the DM3730 I am using it appears to be RM_RSTST_SGX but this is
> is inconsistent with the SGX notes in section 8.2.1.2 of the DM3730
> TRM.
>
> I want to make sure the SGX_FCLK is properly set to which I beleive
> shoudld 192MHz, but I am not sure which macros are the proper ones.
>
> diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
> index 8a2b253..3f69d90 100644
> --- a/arch/arm/boot/dts/omap3.dtsi
> +++ b/arch/arm/boot/dts/omap3.dtsi
> @@ -564,6 +564,14 @@
>                         status = "disabled";
>                 };
>
> +               sgx: sgx@5000000 {
> +                       compatible = "ti,sgx";
> +                       ti,hwmods = "gfx";

fixing hwmods here to match that of the device tree still yields me an
error, but it fixes the reset issue. So I think I am starting to
understand it a bit more, but there are a lot of hwmods that I don't
understand.

[    7.767059] Unable to handle kernel NULL pointer dereference at
virtual address 00000000
[    7.775817] pgd = cf7a0000
[    7.778686] [00000000] *pgd=8f790831, *pte=00000000, *ppte=00000000
[    7.785461] Internal error: Oops: 17 [#1] SMP ARM
[    7.790435] Modules linked in: pvrsrvkm(O+) cpufreq_dt(+)
leds_gpio(+) thermal_sys pwm_omap_dmtimer(+) led_class gpio_keys(+)
panel_dpi(+) hwmon pwm_bl(+) snd_soc_omap_mcbsp snd_soc_omap omap_wdt
omap_hdq wire cn phy_twl4030_usb omap2430 musb_hdrc udc_core
twl4030_wdt rtc_twl snd_soc_twl4030 ehci_omap snd_soc_core
snd_pcm_dmaengine pwm_twl_led snd_pcm ehci_hcd snd_timer
twl4030_pwrbutton pwm_twl snd twl4030_charger twl4030_keypad soundcore
matrix_keymap industrialio ohci_omap3 ohci_hcd usbcore usb_common
tsc2004 tsc200x_core hsi omapdss
[    7.841003] CPU: 0 PID: 106 Comm: udevd Tainted: G           O    4.4.19 #4
[    7.848327] Hardware name: Generic OMAP36xx (Flattened Device Tree)
[    7.854949] task: cf788440 ti: cf79e000 task.ti: cf79e000
[    7.860870] PC is at PVRSRVDriverProbe+0x44/0x9c [pvrsrvkm]
[    7.866790] LR is at platform_drv_probe+0x4c/0xb0

[stuff deleted]

[    8.108886] [<bf2085dc>] (PVRSRVDriverProbe [pvrsrvkm]) from
[<c03f7b24>] (platform_drv_probe+0x4c/0xb0)
[    8.118896] [<c03f7b24>] (platform_drv_probe) from [<c03f5fc0>]
(driver_probe_device+0x1f4/0x2f8)
[    8.128265] [<c03f5fc0>] (driver_probe_device) from [<c03f6158>]
(__driver_attach+0x94/0x98)
[    8.137176] [<c03f6158>] (__driver_attach) from [<c03f4420>]
(bus_for_each_dev+0x6c/0xa0)
[    8.145812] [<c03f4420>] (bus_for_each_dev) from [<c03f5584>]
(bus_add_driver+0x18c/0x214)
[    8.154541] [<c03f5584>] (bus_add_driver) from [<c03f6b90>]
(driver_register+0x78/0xf8)
[    8.163085] [<c03f6b90>] (driver_register) from [<bf228064>]
(PVRCore_Init+0x64/0x15c [pvrsrvkm])
[    8.172576] [<bf228064>] (PVRCore_Init [pvrsrvkm]) from
[<c000980c>] (do_one_initcall+0x80/0x1e0)
[    8.181976] [<c000980c>] (do_one_initcall) from [<c0120480>]
(do_init_module+0x5c/0x1cc)
[    8.190490] [<c0120480>] (do_init_module) from [<c00cf76c>]
(load_module+0x1c10/0x2164)
[    8.198944] [<c00cf76c>] (load_module) from [<c00cfea4>]
(SyS_finit_module+0x7c/0x90)
[    8.207214] [<c00cfea4>] (SyS_finit_module) from [<c000f700>]
(ret_fast_syscall+0x0/0x1c)
[    8.215850] Code: e59f1050 e1a00005 eb47a9af ea000004 (e5932000)
[    8.222473] ---[ end trace e34ac006dee82702 ]---



So I think I am closer, but I don't know what is causing the "nable to
handle kernel NULL pointer dereference at virtual address 00000000"
inside platform_drv_probe.


> +                       reg = <0x50000000 0x1000000>;
> +                       interrupts = <21>;
> +                       /* resets = <&prcm 0>; */
> +               };
> +
>                 sham: sham@480c3000 {
>                         compatible = "ti,omap3-sham";
>                         ti,hwmods = "sham";
> diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> index aff78d5..ca2fbb3 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> @@ -3654,6 +3654,52 @@ static struct omap_hwmod_ocp_if omap34xx_l4_core__ssi = {
>         .user           = OCP_USER_MPU | OCP_USER_SDMA,
>  };
>
> +
> +/* gfx */
> +/* Pseudo hwmod for reset control purpose only */
> +
> +
> +static struct omap_hwmod_class omap3xxx_gfx_hwmod_class = {
> +        .name   = "sgx",
> +};
> +
> +static struct omap_hwmod_rst_info omap3xxx_gfx_resets[] = {
> +        { .name = "sgx", .rst_shift = 0, .st_shift = 0},
> +};
> +
> +struct omap_hwmod omap3xx_gfx_hwmod = {
> +        .name           = "sgx",
> +        .class          = &omap3xxx_gfx_hwmod_class,
> +        .clkdm_name     = "sgx_clkdm",
> +        .main_clk       = "sgx_fck",
> +        .prcm           = {
> +                       .omap2 = {
> +                               .module_offs = OMAP3430ES2_SGX_MOD,
> +                               .prcm_reg_id = 1,
> +                               .module_bit = OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT,
> +                       }
> +        },
> +        .rst_lines      = omap3xxx_gfx_resets,
> +        .rst_lines_cnt  = ARRAY_SIZE(omap3xxx_gfx_resets),
> +};
> +
> +static struct omap_hwmod_addr_space omap3xxx_sgx_addrs[] = {
> +       {
> +               .pa_start       = 0x50000000,
> +               .pa_end         = 0x5000ff0c,
> +               .flags          = ADDR_TYPE_RT,
> +       },
> +       { }
> +};
> +
> +/* l3_main -> sgx */
> +static struct omap_hwmod_ocp_if omap3xxx_l3_main__sgx = {
> +       .master         = &omap3xxx_l3_main_hwmod,
> +       .slave          = &omap3xx_gfx_hwmod,
> +       .addr           = omap3xxx_sgx_addrs,
> +       .user           = OCP_USER_MPU | OCP_USER_SDMA,
> +};
> +
>  static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = {
>         &omap3xxx_l3_main__l4_core,
>         &omap3xxx_l3_main__l4_per,
> @@ -3701,6 +3747,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = {
>         &omap34xx_l4_core__mcspi4,
>         &omap3xxx_l4_wkup__counter_32k,
>         &omap3xxx_l3_main__gpmc,
> +       &omap3xxx_l3_main__sgx,
>         NULL,
>  };
>
> diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
> index 339b859..b700f26 100644
> --- a/arch/arm/mach-omap2/pdata-quirks.c
> +++ b/arch/arm/mach-omap2/pdata-quirks.c
> @@ -24,6 +24,7 @@
>  #include <linux/platform_data/iommu-omap.h>
>  #include <linux/platform_data/wkup_m3.h>
>  #include <linux/platform_data/pwm_omap_dmtimer.h>
> +#include <linux/platform_data/sgx-omap.h>
>  #include <plat/dmtimer.h>
>
>  #include "common.h"
> @@ -382,6 +383,12 @@ static void __init omap3_pandora_legacy_init(void)
>         omap_hsmmc_late_init(pandora_mmc3);
>         pandora_wl1251_init();
>  }
> +
> +static struct gfx_sgx_platform_data gfx_pdata = {
> +       .reset_name = "sgx",
> +       .deassert_reset = omap_device_deassert_hardreset,
> +};
> +
>  #endif /* CONFIG_ARCH_OMAP3 */
>
>  #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
> @@ -479,6 +486,8 @@ static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
>         OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL),
>         OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0",
>                        &am35xx_emac_pdata),
> +   OF_DEV_AUXDATA("ti,sgx", 0x50000000, "50000000.sgx",
> +                               &gfx_pdata),
>  #endif
>  #ifdef CONFIG_SOC_AM33XX
>         OF_DEV_AUXDATA("ti,am3352-wkup-m3", 0x44d00000, "44d00000.wkup_m3",
> diff --git a/include/linux/platform_data/sgx-omap.h b/include/linux/platform_data/sgx-omap.h
> new file mode 100644
> index 0000000..aa59b2c
> --- /dev/null
> +++ b/include/linux/platform_data/sgx-omap.h
> @@ -0,0 +1,22 @@
> +/*
> + * SGX Graphics Driver Platform Data
> + *
> + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
> + *     Darren Etheridge <detheridge@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether express or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +#include <linux/platform_device.h>
> +
> +struct gfx_sgx_platform_data {
> +       const char *reset_name;
> +
> +       int (*deassert_reset)(struct platform_device *pdev, const char *name);
> +};
> --
> 2.7.4
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Tony Lindgren Sept. 2, 2016, 8:50 p.m. UTC | #2
* aford173@gmail.com <aford173@gmail.com> [160902 12:25]:
> --- a/arch/arm/boot/dts/omap3.dtsi
> +++ b/arch/arm/boot/dts/omap3.dtsi
> @@ -564,6 +564,14 @@
>  			status = "disabled";
>  		};
>  
> +		sgx: sgx@5000000 {
> +			compatible = "ti,sgx";
> +			ti,hwmods = "gfx";

I think you may have a naming mismatch between "gfx" and
"sgx"?

> --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> @@ -3654,6 +3654,52 @@ static struct omap_hwmod_ocp_if omap34xx_l4_core__ssi = {
>  	.user		= OCP_USER_MPU | OCP_USER_SDMA,
>  };
>  
> +
> +/* gfx */
> +/* Pseudo hwmod for reset control purpose only */
> +
> +
> +static struct omap_hwmod_class omap3xxx_gfx_hwmod_class = {
> +        .name   = "sgx",
> +};
> +
> +static struct omap_hwmod_rst_info omap3xxx_gfx_resets[] = {
> +        { .name = "sgx", .rst_shift = 0, .st_shift = 0},
> +};
> +
> +struct omap_hwmod omap3xx_gfx_hwmod = {
> +        .name           = "sgx",
> +        .class          = &omap3xxx_gfx_hwmod_class,
> +        .clkdm_name     = "sgx_clkdm",
> +        .main_clk       = "sgx_fck",
> +        .prcm           = {
> +			.omap2 = {
> +				.module_offs = OMAP3430ES2_SGX_MOD,
> +				.prcm_reg_id = 1,
> +				.module_bit = OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT,
> +			}
> +        },
> +        .rst_lines      = omap3xxx_gfx_resets,
> +        .rst_lines_cnt  = ARRAY_SIZE(omap3xxx_gfx_resets),
> +};

You're missing the stuff hwmod is really needed for, the
OCP_SYSCONFIG and others for rev_offs, sysc_offs and
sysc_flags. See for example omap44xx_gpu_sysc. Note that
omap3 does not have clkctrl_offs.

Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Suman Anna Sept. 2, 2016, 9:23 p.m. UTC | #3
Hi Adam,

On 09/02/2016 02:25 PM, aford173@gmail.com wrote:
> From: Adam Ford <aford173@gmail.com>
> 
> Sorry about the wordy email.
> 
> The reset controller stuff needs an overhaul, but this is an attempt
> to allow the last revision of the SGX driver to work with a modern kernel.
> 
> Unfortunately, I get an error when I build the SGX driver:
> 
> pvrsrvkm pvrsrvkm: SGX Platform data missing deassert_reset!
> 
> So it's obviously missing something.  If someone can point me in
> the righ direction. I need to deassert that by writing to a register
> but I am not sure exactly how to go about that.
> 
> On the DM3730 I am using it appears to be RM_RSTST_SGX but this is
> is inconsistent with the SGX notes in section 8.2.1.2 of the DM3730
> TRM.
> 
> I want to make sure the SGX_FCLK is properly set to which I beleive
> shoudld 192MHz, but I am not sure which macros are the proper ones.
> 
> diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
> index 8a2b253..3f69d90 100644
> --- a/arch/arm/boot/dts/omap3.dtsi
> +++ b/arch/arm/boot/dts/omap3.dtsi
> @@ -564,6 +564,14 @@
>  			status = "disabled";
>  		};
>  
> +		sgx: sgx@5000000 {

You are missing one zero

> +			compatible = "ti,sgx";

This is way too generic compatible. I suggest you take a look at the TI
tree once and binding.

> +			ti,hwmods = "gfx";
> +			reg = <0x50000000 0x1000000>;
> +			interrupts = <21>;
> +			/* resets = <&prcm 0>; */
> +		};
> +
>  		sham: sham@480c3000 {
>  			compatible = "ti,omap3-sham";
>  			ti,hwmods = "sham";
> diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> index aff78d5..ca2fbb3 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> @@ -3654,6 +3654,52 @@ static struct omap_hwmod_ocp_if omap34xx_l4_core__ssi = {
>  	.user		= OCP_USER_MPU | OCP_USER_SDMA,
>  };
>  
> +
> +/* gfx */
> +/* Pseudo hwmod for reset control purpose only */
> +
> +
> +static struct omap_hwmod_class omap3xxx_gfx_hwmod_class = {
> +        .name   = "sgx",
> +};
> +
> +static struct omap_hwmod_rst_info omap3xxx_gfx_resets[] = {
> +        { .name = "sgx", .rst_shift = 0, .st_shift = 0},
> +};
> +
> +struct omap_hwmod omap3xx_gfx_hwmod = {
> +        .name           = "sgx",
> +        .class          = &omap3xxx_gfx_hwmod_class,
> +        .clkdm_name     = "sgx_clkdm",
> +        .main_clk       = "sgx_fck",
> +        .prcm           = {
> +			.omap2 = {
> +				.module_offs = OMAP3430ES2_SGX_MOD,
> +				.prcm_reg_id = 1,
> +				.module_bit = OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT,
> +			}
> +        },
> +        .rst_lines      = omap3xxx_gfx_resets,
> +        .rst_lines_cnt  = ARRAY_SIZE(omap3xxx_gfx_resets),
> +};
> +
> +static struct omap_hwmod_addr_space omap3xxx_sgx_addrs[] = {
> +	{
> +		.pa_start	= 0x50000000,
> +		.pa_end		= 0x5000ff0c,
> +		.flags		= ADDR_TYPE_RT,
> +	},
> +	{ }
> +};

OMAP3 should be DT-boot only now, so you can remove the legacy-style
addr_space

> +
> +/* l3_main -> sgx */
> +static struct omap_hwmod_ocp_if omap3xxx_l3_main__sgx = {
> +	.master		= &omap3xxx_l3_main_hwmod,
> +	.slave		= &omap3xx_gfx_hwmod,
> +	.addr		= omap3xxx_sgx_addrs,
> +	.user		= OCP_USER_MPU | OCP_USER_SDMA,
> +};
> +
>  static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = {
>  	&omap3xxx_l3_main__l4_core,
>  	&omap3xxx_l3_main__l4_per,
> @@ -3701,6 +3747,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = {
>  	&omap34xx_l4_core__mcspi4,
>  	&omap3xxx_l4_wkup__counter_32k,
>  	&omap3xxx_l3_main__gpmc,
> +	&omap3xxx_l3_main__sgx,
>  	NULL,
>  };
>  
> diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
> index 339b859..b700f26 100644
> --- a/arch/arm/mach-omap2/pdata-quirks.c
> +++ b/arch/arm/mach-omap2/pdata-quirks.c
> @@ -24,6 +24,7 @@
>  #include <linux/platform_data/iommu-omap.h>
>  #include <linux/platform_data/wkup_m3.h>
>  #include <linux/platform_data/pwm_omap_dmtimer.h>
> +#include <linux/platform_data/sgx-omap.h>
>  #include <plat/dmtimer.h>
>  
>  #include "common.h"
> @@ -382,6 +383,12 @@ static void __init omap3_pandora_legacy_init(void)
>  	omap_hsmmc_late_init(pandora_mmc3);
>  	pandora_wl1251_init();
>  }
> +
> +static struct gfx_sgx_platform_data gfx_pdata = {
> +	.reset_name = "sgx",
> +	.deassert_reset = omap_device_deassert_hardreset,

you would need the .assert_reset hook as well. Otherwise, the driver is
not doing a clean job of balancing the resets when you install and
remove the module.

> +};
> +
>  #endif /* CONFIG_ARCH_OMAP3 */
>  
>  #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
> @@ -479,6 +486,8 @@ static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
>  	OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL),
>  	OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0",
>  		       &am35xx_emac_pdata),
> +   OF_DEV_AUXDATA("ti,sgx", 0x50000000, "50000000.sgx",
> +				&gfx_pdata),

looks like spaces (guessing manual copy-paste), please make sure you run
checkpatch.

>  #endif
>  #ifdef CONFIG_SOC_AM33XX
>  	OF_DEV_AUXDATA("ti,am3352-wkup-m3", 0x44d00000, "44d00000.wkup_m3",
> diff --git a/include/linux/platform_data/sgx-omap.h b/include/linux/platform_data/sgx-omap.h
> new file mode 100644
> index 0000000..aa59b2c
> --- /dev/null
> +++ b/include/linux/platform_data/sgx-omap.h
> @@ -0,0 +1,22 @@
> +/*
> + * SGX Graphics Driver Platform Data
> + *
> + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
> + *	Darren Etheridge <detheridge@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether express or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +#include <linux/platform_device.h>
> +
> +struct gfx_sgx_platform_data {
> +	const char *reset_name;
> +
> +	int (*deassert_reset)(struct platform_device *pdev, const char *name);

missing assert_reset ops.

regards
Suman

> +};
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
index 8a2b253..3f69d90 100644
--- a/arch/arm/boot/dts/omap3.dtsi
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -564,6 +564,14 @@ 
 			status = "disabled";
 		};
 
+		sgx: sgx@5000000 {
+			compatible = "ti,sgx";
+			ti,hwmods = "gfx";
+			reg = <0x50000000 0x1000000>;
+			interrupts = <21>;
+			/* resets = <&prcm 0>; */
+		};
+
 		sham: sham@480c3000 {
 			compatible = "ti,omap3-sham";
 			ti,hwmods = "sham";
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index aff78d5..ca2fbb3 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -3654,6 +3654,52 @@  static struct omap_hwmod_ocp_if omap34xx_l4_core__ssi = {
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+
+/* gfx */
+/* Pseudo hwmod for reset control purpose only */
+
+
+static struct omap_hwmod_class omap3xxx_gfx_hwmod_class = {
+        .name   = "sgx",
+};
+
+static struct omap_hwmod_rst_info omap3xxx_gfx_resets[] = {
+        { .name = "sgx", .rst_shift = 0, .st_shift = 0},
+};
+
+struct omap_hwmod omap3xx_gfx_hwmod = {
+        .name           = "sgx",
+        .class          = &omap3xxx_gfx_hwmod_class,
+        .clkdm_name     = "sgx_clkdm",
+        .main_clk       = "sgx_fck",
+        .prcm           = {
+			.omap2 = {
+				.module_offs = OMAP3430ES2_SGX_MOD,
+				.prcm_reg_id = 1,
+				.module_bit = OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT,
+			}
+        },
+        .rst_lines      = omap3xxx_gfx_resets,
+        .rst_lines_cnt  = ARRAY_SIZE(omap3xxx_gfx_resets),
+};
+
+static struct omap_hwmod_addr_space omap3xxx_sgx_addrs[] = {
+	{
+		.pa_start	= 0x50000000,
+		.pa_end		= 0x5000ff0c,
+		.flags		= ADDR_TYPE_RT,
+	},
+	{ }
+};
+
+/* l3_main -> sgx */
+static struct omap_hwmod_ocp_if omap3xxx_l3_main__sgx = {
+	.master		= &omap3xxx_l3_main_hwmod,
+	.slave		= &omap3xx_gfx_hwmod,
+	.addr		= omap3xxx_sgx_addrs,
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = {
 	&omap3xxx_l3_main__l4_core,
 	&omap3xxx_l3_main__l4_per,
@@ -3701,6 +3747,7 @@  static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = {
 	&omap34xx_l4_core__mcspi4,
 	&omap3xxx_l4_wkup__counter_32k,
 	&omap3xxx_l3_main__gpmc,
+	&omap3xxx_l3_main__sgx,
 	NULL,
 };
 
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
index 339b859..b700f26 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -24,6 +24,7 @@ 
 #include <linux/platform_data/iommu-omap.h>
 #include <linux/platform_data/wkup_m3.h>
 #include <linux/platform_data/pwm_omap_dmtimer.h>
+#include <linux/platform_data/sgx-omap.h>
 #include <plat/dmtimer.h>
 
 #include "common.h"
@@ -382,6 +383,12 @@  static void __init omap3_pandora_legacy_init(void)
 	omap_hsmmc_late_init(pandora_mmc3);
 	pandora_wl1251_init();
 }
+
+static struct gfx_sgx_platform_data gfx_pdata = {
+	.reset_name = "sgx",
+	.deassert_reset = omap_device_deassert_hardreset,
+};
+
 #endif /* CONFIG_ARCH_OMAP3 */
 
 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
@@ -479,6 +486,8 @@  static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
 	OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL),
 	OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0",
 		       &am35xx_emac_pdata),
+   OF_DEV_AUXDATA("ti,sgx", 0x50000000, "50000000.sgx",
+				&gfx_pdata),
 #endif
 #ifdef CONFIG_SOC_AM33XX
 	OF_DEV_AUXDATA("ti,am3352-wkup-m3", 0x44d00000, "44d00000.wkup_m3",
diff --git a/include/linux/platform_data/sgx-omap.h b/include/linux/platform_data/sgx-omap.h
new file mode 100644
index 0000000..aa59b2c
--- /dev/null
+++ b/include/linux/platform_data/sgx-omap.h
@@ -0,0 +1,22 @@ 
+/*
+ * SGX Graphics Driver Platform Data
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *	Darren Etheridge <detheridge@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/platform_device.h>
+
+struct gfx_sgx_platform_data {
+	const char *reset_name;
+
+	int (*deassert_reset)(struct platform_device *pdev, const char *name);
+};