Message ID | 51103A25.9010401@ti.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
* Jon Hunter <jon-hunter@ti.com> [130204 14:49]: > > On 02/04/2013 04:12 PM, Jon Hunter wrote: > > > > On 02/01/2013 03:51 PM, Tony Lindgren wrote: > > > >> How about let's fix this properly to start with so we don't add > >> more blockers moving this code to drivers/bus? > >> > >> Looks like gpmc_mem_init() gets called from gpmc_probe() so > >> we can pass that information in pdev. > > > > I have re-worked this a bit to use platform data. I have also update > > the logic for testing internal/external boot on omap2430 which is > > different from omap2420 (according to the TRM). However, I have only > > boot tested on omap2420. > > > > Do you know why this was changed in the first place? See below ... > > > > http://permalink.gmane.org/gmane.linux.kernel.commits.head/95931 > > > > Heres what I have now ... > > Updated patch (I was missing a kfree()). By the way, this is based > upon the apollon removal patch. I understand probably needs to be > rebased on your latest gpmc series too. Yeah makes sense to me thanks. I'll figure out where to apply this so we don't get too many dependencies. Regards, Tony
On 02/05/2013 05:34 PM, Tony Lindgren wrote: > * Jon Hunter <jon-hunter@ti.com> [130204 14:49]: >> >> On 02/04/2013 04:12 PM, Jon Hunter wrote: >>> >>> On 02/01/2013 03:51 PM, Tony Lindgren wrote: >>> >>>> How about let's fix this properly to start with so we don't add >>>> more blockers moving this code to drivers/bus? >>>> >>>> Looks like gpmc_mem_init() gets called from gpmc_probe() so >>>> we can pass that information in pdev. >>> >>> I have re-worked this a bit to use platform data. I have also update >>> the logic for testing internal/external boot on omap2430 which is >>> different from omap2420 (according to the TRM). However, I have only >>> boot tested on omap2420. >>> >>> Do you know why this was changed in the first place? See below ... >>> >>> http://permalink.gmane.org/gmane.linux.kernel.commits.head/95931 >>> >>> Heres what I have now ... >> >> Updated patch (I was missing a kfree()). By the way, this is based >> upon the apollon removal patch. I understand probably needs to be >> rebased on your latest gpmc series too. > > Yeah makes sense to me thanks. I'll figure out where to apply this > so we don't get too many dependencies. Actually, let me look into this a bit more. It appears that for all omap2+ devices NOR should be mapped to CS0 at 0x08000000. So I am wondering if the boot-loader is re-mapping the CS0 space. If it is then may be we can avoid having such hacks in the kernel by fixing the bootloader. To date only the apollon board has really had this problem and I need to check what I have on my H4 (which has been hacked by me ;-) Cheers Jon
* Jon Hunter <jon-hunter@ti.com> [130205 16:26]: > > Actually, let me look into this a bit more. It appears that for all > omap2+ devices NOR should be mapped to CS0 at 0x08000000. So I am > wondering if the boot-loader is re-mapping the CS0 space. If it is then > may be we can avoid having such hacks in the kernel by fixing the > bootloader. To date only the apollon board has really had this problem > and I need to check what I have on my H4 (which has been hacked by me ;-) OK. Yeah sorry I don't remember the history of why the different mappings were needed. It could be it was just needed to keep some devices working that were only initialized in the bootloader like you're suspecting. Tony
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index a124849..aa58258 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -20,6 +20,7 @@ #include <linux/err.h> #include <linux/clk.h> #include <linux/ioport.h> +#include <linux/slab.h> #include <linux/spinlock.h> #include <linux/io.h> #include <linux/module.h> @@ -32,6 +33,7 @@ #include "soc.h" #include "common.h" +#include "control.h" #include "omap_device.h" #include "gpmc.h" @@ -87,7 +89,6 @@ #define GPMC_MEM_START 0x00000000 #define GPMC_MEM_END 0x3FFFFFFF -#define BOOT_ROM_SPACE 0x100000 /* 1MB */ #define GPMC_CHUNK_SHIFT 24 /* 16 MB */ #define GPMC_SECTION_SHIFT 28 /* 128 MB */ @@ -775,16 +776,11 @@ static void gpmc_mem_exit(void) } -static int gpmc_mem_init(void) +static int gpmc_mem_init(u32 offset) { int cs, rc; - unsigned long boot_rom_space = 0; - /* never allocate the first page, to facilitate bug detection; - * even if we didn't boot from ROM. - */ - boot_rom_space = BOOT_ROM_SPACE; - gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space; + gpmc_mem_root.start = GPMC_MEM_START + offset; gpmc_mem_root.end = GPMC_MEM_END; /* Reserve all regions that has been set up by bootloader */ @@ -1124,6 +1120,12 @@ static int gpmc_probe(struct platform_device *pdev) int rc; u32 l; struct resource *res; + struct gpmc_platform_data *pdata = pdev->dev.platform_data; + + if (!pdata) { + dev_err(&pdev->dev, "%s: no platform data.\n", __func__); + return -ENODEV; + } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) @@ -1161,7 +1163,7 @@ static int gpmc_probe(struct platform_device *pdev) dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l), GPMC_REVISION_MINOR(l)); - rc = gpmc_mem_init(); + rc = gpmc_mem_init(pdata->gpmc_rom_space); if (IS_ERR_VALUE(rc)) { clk_disable_unprepare(gpmc_l3_clk); clk_put(gpmc_l3_clk); @@ -1213,18 +1215,54 @@ static int __init omap_gpmc_init(void) { struct omap_hwmod *oh; struct platform_device *pdev; + struct gpmc_platform_data *pdata; char *oh_name = "gpmc"; + pdata = kzalloc(sizeof(struct gpmc_platform_data), GFP_KERNEL); + if (!pdata) { + pr_err("%s: No memory for gpmc\n", __func__); + return -ENOMEM; + } + + /* + * The first 1MB of GPMC address space is mapped to the internal + * ROM. OMAP2 devices are an exception to this where the first + * 1MB may be mapped to the GPMC. OMAP2 devices that boot from + * external memory devices, will map CS0 to the start of the + * GPMC address space (0x0). We can test this by checking the + * SYS_BOOT pins. + * + * OMAP2420 SYS_BOOT[3] = 1b, then GPMC CS0 is mapped to 0x0. + * OMAP2430 SYS_BOOT[2:1] = 00b, then GPMC CS0 is mapped to 0x0. + */ + pdata->gpmc_rom_space = SZ_1M; + + if (cpu_is_omap242x()) { + if (!(omap_ctrl_readl(OMAP24XX_CONTROL_STATUS) & + OMAP2_SYSBOOT_3_MASK)) + pdata->gpmc_rom_space = 0; + } else if (cpu_is_omap243x()) { + if (!(omap_ctrl_readl(OMAP24XX_CONTROL_STATUS) & + (OMAP2_SYSBOOT_2_MASK | OMAP2_SYSBOOT_1_MASK))) + pdata->gpmc_rom_space = 0; + } + oh = omap_hwmod_lookup(oh_name); if (!oh) { pr_err("Could not look up %s\n", oh_name); return -ENODEV; } - pdev = omap_device_build(DEVICE_NAME, -1, oh, NULL, 0, NULL, 0, 0); + pdev = omap_device_build(DEVICE_NAME, -1, oh, pdata, sizeof(*pdata), + NULL, 0, 0); WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); - return IS_ERR(pdev) ? PTR_ERR(pdev) : 0; + if (IS_ERR(pdev)) { + kfree(pdata); + return PTR_ERR(pdev); + } + + return 0; } postcore_initcall(omap_gpmc_init); diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h index fe0a844..b33ef26 100644 --- a/arch/arm/mach-omap2/gpmc.h +++ b/arch/arm/mach-omap2/gpmc.h @@ -189,6 +189,11 @@ struct gpmc_device_timings { bool we_xdelay; }; +/* GPMC platform data */ +struct gpmc_platform_data { + u32 gpmc_rom_space; +}; + extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t, struct gpmc_device_timings *dev_t);