[PATCH v2 06/10] mtd: nand: omap2: obtain memory from resource

2012-06-13 Thread Afzal Mohammed
gpmc initialization done by platform code now updates struct resource
with the address space alloted for nand. Use this interface to obtain
memory rather than relying on platform data field - phys_base.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/plat-omap/include/plat/nand.h |1 -
 drivers/mtd/nand/omap2.c   |   19 +++
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/nand.h 
b/arch/arm/plat-omap/include/plat/nand.h
index 86e4d9c..290cef5 100644
--- a/arch/arm/plat-omap/include/plat/nand.h
+++ b/arch/arm/plat-omap/include/plat/nand.h
@@ -26,7 +26,6 @@ struct omap_nand_platform_data {
booldev_ready;
int gpmc_irq;
enum nand_ioxfer_type;
-   unsigned long   phys_base;
int devsize;
enum omap_ecc   ecc_opt;
struct gpmc_nand_regs   reg;
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 1d138fe..318ed8a 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -132,6 +132,7 @@ struct omap_nand_info {
 
int gpmc_cs;
unsigned long   phys_base;
+   unsigned long   mem_size;
struct completion   comp;
int dma_ch;
int gpmc_irq;
@@ -1279,6 +1280,7 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
struct omap_nand_platform_data  *pdata;
int err;
int i, offset;
+   struct resource *res;
 
pdata = pdev-dev.platform_data;
if (pdata == NULL) {
@@ -1298,7 +1300,6 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
info-pdev = pdev;
 
info-gpmc_cs   = pdata-cs;
-   info-phys_base = pdata-phys_base;
info-reg   = pdata-reg;
 
info-mtd.priv  = info-nand;
@@ -1311,13 +1312,23 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
/* NAND write protect off */
gpmc_cs_configure(info-gpmc_cs, GPMC_CONFIG_WP, 0);
 
-   if (!request_mem_region(info-phys_base, NAND_IO_SIZE,
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   if (res == NULL) {
+   err = -EINVAL;
+   dev_err(pdev-dev, error getting memory resource\n);
+   goto out_free_info;
+   }
+
+   info-phys_base = res-start;
+   info-mem_size = resource_size(res);
+
+   if (!request_mem_region(info-phys_base, info-mem_size,
pdev-dev.driver-name)) {
err = -EBUSY;
goto out_free_info;
}
 
-   info-nand.IO_ADDR_R = ioremap(info-phys_base, NAND_IO_SIZE);
+   info-nand.IO_ADDR_R = ioremap(info-phys_base, info-mem_size);
if (!info-nand.IO_ADDR_R) {
err = -ENOMEM;
goto out_release_mem_region;
@@ -1474,7 +1485,7 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
return 0;
 
 out_release_mem_region:
-   release_mem_region(info-phys_base, NAND_IO_SIZE);
+   release_mem_region(info-phys_base, info-mem_size);
 out_free_info:
kfree(info);
 
-- 
1.7.10.2

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


[PATCH v2 07/10] mtd: onenand: omap2: obtain memory from resource

2012-06-13 Thread Afzal Mohammed
gpmc initialization for onenand done by platform code now provides
onenand address space as memory resource. Hence remove usage of
gpmc_cs_request in onenand driver and obtain memory details from
resource structure.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 drivers/mtd/onenand/omap2.c |   29 -
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 398a827..3ff893d 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -48,13 +48,13 @@
 
 #define DRIVER_NAME omap2-onenand
 
-#define ONENAND_IO_SIZESZ_128K
 #define ONENAND_BUFRAM_SIZE(1024 * 5)
 
 struct omap2_onenand {
struct platform_device *pdev;
int gpmc_cs;
unsigned long phys_base;
+   unsigned int mem_size;
int gpio_irq;
struct mtd_info mtd;
struct onenand_chip onenand;
@@ -626,6 +626,7 @@ static int __devinit omap2_onenand_probe(struct 
platform_device *pdev)
struct omap2_onenand *c;
struct onenand_chip *this;
int r;
+   struct resource *res;
 
pdata = pdev-dev.platform_data;
if (pdata == NULL) {
@@ -647,20 +648,24 @@ static int __devinit omap2_onenand_probe(struct 
platform_device *pdev)
c-gpio_irq = 0;
}
 
-   r = gpmc_cs_request(c-gpmc_cs, ONENAND_IO_SIZE, c-phys_base);
-   if (r  0) {
-   dev_err(pdev-dev, Cannot request GPMC CS\n);
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   if (res == NULL) {
+   r = -EINVAL;
+   dev_err(pdev-dev, error getting memory resource\n);
goto err_kfree;
}
 
-   if (request_mem_region(c-phys_base, ONENAND_IO_SIZE,
+   c-phys_base = res-start;
+   c-mem_size = resource_size(res);
+
+   if (request_mem_region(c-phys_base, c-mem_size,
   pdev-dev.driver-name) == NULL) {
-   dev_err(pdev-dev, Cannot reserve memory region at 0x%08lx, 
-   size: 0x%x\n, c-phys_base, ONENAND_IO_SIZE);
+   dev_err(pdev-dev, Cannot reserve memory region at 0x%08lx, 
size: 0x%x\n,
+   c-phys_base, c-mem_size);
r = -EBUSY;
-   goto err_free_cs;
+   goto err_kfree;
}
-   c-onenand.base = ioremap(c-phys_base, ONENAND_IO_SIZE);
+   c-onenand.base = ioremap(c-phys_base, c-mem_size);
if (c-onenand.base == NULL) {
r = -ENOMEM;
goto err_release_mem_region;
@@ -776,9 +781,7 @@ err_release_gpio:
 err_iounmap:
iounmap(c-onenand.base);
 err_release_mem_region:
-   release_mem_region(c-phys_base, ONENAND_IO_SIZE);
-err_free_cs:
-   gpmc_cs_free(c-gpmc_cs);
+   release_mem_region(c-phys_base, c-mem_size);
 err_kfree:
kfree(c);
 
@@ -800,7 +803,7 @@ static int __devexit omap2_onenand_remove(struct 
platform_device *pdev)
gpio_free(c-gpio_irq);
}
iounmap(c-onenand.base);
-   release_mem_region(c-phys_base, ONENAND_IO_SIZE);
+   release_mem_region(c-phys_base, c-mem_size);
gpmc_cs_free(c-gpmc_cs);
kfree(c);
 
-- 
1.7.10.2

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


[PATCH v2 08/10] ARM: OMAP2+: gpmc: Modify interrupt handling

2012-06-13 Thread Afzal Mohammed
Modify interrupt handling such that interrupts can be handled by GPMC
client drivers using standard interrupt APIs rather than requiring
the drivers to have knowledge about GPMC interrupt handling. Currently
only NAND related interrupts has been considered (which is the case
even without this change) as the only user of GPMC interrupt is NAND.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |  136 
 arch/arm/plat-omap/include/plat/gpmc.h |1 +
 2 files changed, 120 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index a2c0588..578fd4c 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -78,6 +78,15 @@
 #define ENABLE_PREFETCH(0x1  7)
 #define DMA_MPU_MODE   2
 
+/* XXX: Only NAND irq has been considered,currently these are the only ones 
used
+ */
+#defineGPMC_NR_IRQ 2
+
+struct gpmc_client_irq {
+   unsignedirq;
+   u32 bitmask;
+};
+
 /* Structure to save gpmc cs context */
 struct gpmc_cs_config {
u32 config1;
@@ -105,6 +114,10 @@ struct omap3_gpmc_regs {
struct gpmc_cs_config cs_context[GPMC_CS_NUM];
 };
 
+static struct gpmc_client_irq gpmc_client_irq[GPMC_NR_IRQ];
+static struct irq_chip gpmc_irq_chip;
+static unsigned gpmc_irq_start;
+
 static struct resource gpmc_mem_root;
 static struct resource gpmc_cs_mem[GPMC_CS_NUM];
 static DEFINE_SPINLOCK(gpmc_mem_lock);
@@ -702,6 +715,97 @@ void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int 
cs)
reg-gpmc_bch_result0 = gpmc_base + GPMC_ECC_BCH_RESULT_0;
 }
 
+int gpmc_get_client_irq(unsigned irq_config)
+{
+   int i;
+
+   if (hweight32(irq_config)  1)
+   return 0;
+
+   for (i = 0; i  GPMC_NR_IRQ; i++)
+   if (gpmc_client_irq[i].bitmask  irq_config)
+   return gpmc_client_irq[i].irq;
+
+   return 0;
+}
+
+static int gpmc_irq_endis(unsigned irq, bool endis)
+{
+   int i;
+   u32 regval;
+
+   for (i = 0; i  GPMC_NR_IRQ; i++)
+   if (irq == gpmc_client_irq[i].irq) {
+   regval = gpmc_read_reg(GPMC_IRQENABLE);
+   if (endis)
+   regval |= gpmc_client_irq[i].bitmask;
+   else
+   regval = ~gpmc_client_irq[i].bitmask;
+   gpmc_write_reg(GPMC_IRQENABLE, regval);
+   break;
+   }
+
+   return 0;
+}
+
+static void gpmc_irq_disable(struct irq_data *p)
+{
+   gpmc_irq_endis(p-irq, false);
+}
+
+static void gpmc_irq_enable(struct irq_data *p)
+{
+   gpmc_irq_endis(p-irq, true);
+}
+
+static void gpmc_irq_noop(struct irq_data *data) { }
+
+static unsigned int gpmc_irq_noop_ret(struct irq_data *data) { return 0; }
+
+static int gpmc_setup_irq(int gpmc_irq)
+{
+   int i;
+   u32 regval;
+
+   if (!gpmc_irq)
+   return -EINVAL;
+
+   gpmc_irq_start = irq_alloc_descs(-1, 0, GPMC_NR_IRQ, 0);
+   if (IS_ERR_VALUE(gpmc_irq_start)) {
+   pr_err(irq_alloc_descs failed\n);
+   return gpmc_irq_start;
+   }
+
+   gpmc_irq_chip.name = gpmc;
+   gpmc_irq_chip.irq_startup = gpmc_irq_noop_ret;
+   gpmc_irq_chip.irq_enable = gpmc_irq_enable;
+   gpmc_irq_chip.irq_disable = gpmc_irq_disable;
+   gpmc_irq_chip.irq_shutdown = gpmc_irq_noop;
+   gpmc_irq_chip.irq_ack = gpmc_irq_noop;
+   gpmc_irq_chip.irq_mask = gpmc_irq_noop;
+   gpmc_irq_chip.irq_unmask = gpmc_irq_noop;
+
+   gpmc_client_irq[0].bitmask = GPMC_IRQ_FIFOEVENTENABLE;
+   gpmc_client_irq[1].bitmask = GPMC_IRQ_COUNT_EVENT;
+
+   for (i = 0; i  GPMC_NR_IRQ; i++) {
+   gpmc_client_irq[i].irq = gpmc_irq_start + i;
+   irq_set_chip_and_handler(gpmc_client_irq[i].irq,
+   gpmc_irq_chip, handle_simple_irq);
+   set_irq_flags(gpmc_client_irq[i].irq,
+   IRQF_VALID | IRQF_NOAUTOEN);
+   }
+
+   /* Disable interrupts */
+   gpmc_write_reg(GPMC_IRQENABLE, 0);
+
+   /* clear interrupts */
+   regval = gpmc_read_reg(GPMC_IRQSTATUS);
+   gpmc_write_reg(GPMC_IRQSTATUS, regval);
+
+   return request_irq(gpmc_irq, gpmc_handle_irq, 0, gpmc, NULL);
+}
+
 static void __init gpmc_mem_init(void)
 {
int cs;
@@ -731,8 +835,8 @@ static void __init gpmc_mem_init(void)
 
 static int __init gpmc_init(void)
 {
-   u32 l, irq;
-   int cs, ret = -EINVAL;
+   u32 l;
+   int ret = -EINVAL;
int gpmc_irq;
char *ck = NULL;
 
@@ -780,16 +884,7 @@ static int __init gpmc_init(void)
gpmc_write_reg(GPMC_SYSCONFIG, l);
gpmc_mem_init();
 
-   /* initalize the irq_chained */
-   irq = OMAP_GPMC_IRQ_BASE;
-   for (cs = 0; cs  GPMC_CS_NUM; cs

[PATCH v2 09/10] ARM: OMAP2+: gpmc-nand: Modify Interrupt handling

2012-06-13 Thread Afzal Mohammed
Now GPMC provides its client with interrupts that can be handled
using the standard interrupt API. Modify GPMC NAND setup to work
with it.

Also disable write protect in GPMC code, so that NAND driver can
be ignorant of GPMC configuration.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc-nand.c |   26 --
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index c0320d2..045596a 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -21,15 +21,23 @@
 #include plat/board.h
 #include plat/gpmc.h
 
-static struct resource gpmc_nand_resource = {
-   .flags  = IORESOURCE_MEM,
+static struct resource gpmc_nand_resource[] = {
+   {
+   .flags  = IORESOURCE_MEM,
+   },
+   {
+   .flags  = IORESOURCE_IRQ,
+   },
+   {
+   .flags  = IORESOURCE_IRQ,
+   },
 };
 
 static struct platform_device gpmc_nand_device = {
.name   = omap2-nand,
.id = 0,
-   .num_resources  = 1,
-   .resource   = gpmc_nand_resource,
+   .num_resources  = ARRAY_SIZE(gpmc_nand_resource),
+   .resource   = gpmc_nand_resource,
 };
 
 static int omap2_nand_gpmc_retime(struct omap_nand_platform_data 
*gpmc_nand_data)
@@ -75,6 +83,7 @@ static int omap2_nand_gpmc_retime(struct 
omap_nand_platform_data *gpmc_nand_data
gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_DEV_SIZE, 0);
gpmc_cs_configure(gpmc_nand_data-cs,
GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND);
+   gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_WP, 0);
err = gpmc_cs_set_timings(gpmc_nand_data-cs, t);
if (err)
return err;
@@ -90,14 +99,19 @@ int __init gpmc_nand_init(struct omap_nand_platform_data 
*gpmc_nand_data)
gpmc_nand_device.dev.platform_data = gpmc_nand_data;
 
err = gpmc_cs_request(gpmc_nand_data-cs, NAND_IO_SIZE,
-   (unsigned long *)gpmc_nand_resource.start);
+   (unsigned long *)gpmc_nand_resource[0].start);
if (err  0) {
dev_err(dev, Cannot request GPMC CS\n);
return err;
}
 
-   gpmc_nand_resource.end = gpmc_nand_resource.start + NAND_IO_SIZE - 1;
+   gpmc_nand_resource[0].end = gpmc_nand_resource[0].start +
+   NAND_IO_SIZE - 1;
 
+   gpmc_nand_resource[1].start =
+   gpmc_get_client_irq(GPMC_IRQ_FIFOEVENTENABLE);
+   gpmc_nand_resource[2].start =
+   gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);
 /* Set timings in GPMC */
err = omap2_nand_gpmc_retime(gpmc_nand_data);
if (err  0) {
-- 
1.7.10.2

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


[PATCH v2 10/10] mtd: nand: omap2: use gpmc provided irqs

2012-06-13 Thread Afzal Mohammed
GPMC platform initialization provides it's clients
with interrupts that can be used through struct
resource. Make use of it for irq mode functionality.

Also now write protect disable is done by GPMC,
hence remove it.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 drivers/mtd/nand/omap2.c |   70 +++---
 1 file changed, 42 insertions(+), 28 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 318ed8a..5193ebb 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -135,7 +135,8 @@ struct omap_nand_info {
unsigned long   mem_size;
struct completion   comp;
int dma_ch;
-   int gpmc_irq;
+   int gpmc_irq_fifo;
+   int gpmc_irq_count;
enum {
OMAP_NAND_IO_READ = 0,  /* read */
OMAP_NAND_IO_WRITE, /* write */
@@ -564,14 +565,12 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev)
 {
struct omap_nand_info *info = (struct omap_nand_info *) dev;
u32 bytes;
-   u32 irq_stat;
 
-   irq_stat = gpmc_read_status(GPMC_GET_IRQ_STATUS);
bytes = readl(info-reg.gpmc_prefetch_status);
bytes = GPMC_PREFETCH_STATUS_FIFO_CNT(bytes);
bytes = bytes   0xFFFC; /* io in multiple of 4 bytes */
if (info-iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */
-   if (irq_stat  0x2)
+   if (this_irq == info-gpmc_irq_count)
goto done;
 
if (info-buf_len  (info-buf_len  bytes))
@@ -588,20 +587,17 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev)
(u32 *)info-buf, bytes  2);
info-buf = info-buf + bytes;
 
-   if (irq_stat  0x2)
+   if (this_irq == info-gpmc_irq_count)
goto done;
}
-   gpmc_cs_configure(info-gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat);
 
return IRQ_HANDLED;
 
 done:
complete(info-comp);
-   /* disable irq */
-   gpmc_cs_configure(info-gpmc_cs, GPMC_ENABLE_IRQ, 0);
 
-   /* clear status */
-   gpmc_cs_configure(info-gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat);
+   disable_irq_nosync(info-gpmc_irq_fifo);
+   disable_irq_nosync(info-gpmc_irq_count);
 
return IRQ_HANDLED;
 }
@@ -635,9 +631,9 @@ static void omap_read_buf_irq_pref(struct mtd_info *mtd, 
u_char *buf, int len)
goto out_copy;
 
info-buf_len = len;
-   /* enable irq */
-   gpmc_cs_configure(info-gpmc_cs, GPMC_ENABLE_IRQ,
-   (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT));
+
+   enable_irq(info-gpmc_irq_count);
+   enable_irq(info-gpmc_irq_fifo);
 
/* waiting for read to complete */
wait_for_completion(info-comp);
@@ -685,12 +681,13 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd,
goto out_copy;
 
info-buf_len = len;
-   /* enable irq */
-   gpmc_cs_configure(info-gpmc_cs, GPMC_ENABLE_IRQ,
-   (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT));
+
+   enable_irq(info-gpmc_irq_count);
+   enable_irq(info-gpmc_irq_fifo);
 
/* waiting for write to complete */
wait_for_completion(info-comp);
+
/* wait for data to flushed-out before reset the prefetch */
tim = 0;
limit = (loops_per_jiffy *  msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS));
@@ -1309,9 +1306,6 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
info-nand.options  = pdata-devsize;
info-nand.options  |= NAND_SKIP_BBTSCAN;
 
-   /* NAND write protect off */
-   gpmc_cs_configure(info-gpmc_cs, GPMC_CONFIG_WP, 0);
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
err = -EINVAL;
@@ -1334,6 +1328,14 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
goto out_release_mem_region;
}
 
+   info-gpmc_irq_fifo = platform_get_irq(pdev, 0);
+   if (info-gpmc_irq_fifo == -ENXIO)
+   dev_warn(pdev-dev, error getting FIFO IRQ\n);
+
+   info-gpmc_irq_count = platform_get_irq(pdev, 1);
+   if (info-gpmc_irq_count == -ENXIO)
+   dev_warn(pdev-dev, error getting TERMINALCOUNT IRQ\n);
+
info-nand.controller = info-controller;
 
info-nand.IO_ADDR_W = info-nand.IO_ADDR_R;
@@ -1389,17 +1391,24 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
break;
 
case NAND_OMAP_PREFETCH_IRQ:
-   err = request_irq(pdata-gpmc_irq,
-   omap_nand_irq, IRQF_SHARED, gpmc-nand, info);
+   err = request_irq(info-gpmc_irq_fifo,  omap_nand_irq

[PATCH v2 0/3] Prepare for GPMC driver conversion

2012-06-16 Thread Afzal Mohammed
Hi,

Objective of this series is to make things easy for GPMC driver
conversion series by separating out more things from driver
conversion series.

This series,
1. Unifies NAND platform initialization functions
2. Prepares OneNAND platform code for gpmc driver migration
3. Handles additional timings in Kernel

This series is based on 3.5-rc1  made on top of
[PATCH v2 00/10] Prepare for GPMC driver conversion (w.r.t MTD)
{http://www.mail-archive.com/linux-omap@vger.kernel.org/msg70096.html}

These changes has been tested with omap3evm  beagle board. Relevant
GPMC peripherals that got tested by this were NAND (beagle) and
OneNAND (using local patches for omap3evm)

Hi Jon,

If you can test these changes on boards having NAND it would be
really helpful. Tony's remaining concern with this series is
whether this would cause NAND filesystem corruption

Regards
Afzal

v2:

1. Make use of timing api for setting clock activation time, and
 remove direct writing to register for clock activation. Peripherals
 making use of it were tusb6010  onenand
2. Move ensuring that async mode in OneNAND has been setup from
 set_sync to setup function, improve commit message

Afzal Mohammed (3):
  ARM: OMAP2+: nand: unify init functions
  ARM: OMAP2+: onenand: prepare for gpmc driver migration
  ARM: OMAP2+: gpmc: handle additional timings

 arch/arm/mach-omap2/board-devkit8000.c |8 +++--
 arch/arm/mach-omap2/board-flash.c  |   45 ++-
 arch/arm/mach-omap2/board-flash.h  |6 ++--
 arch/arm/mach-omap2/board-igep0020.c   |2 +-
 arch/arm/mach-omap2/board-ldp.c|4 +--
 arch/arm/mach-omap2/board-omap3beagle.c|8 +++--
 arch/arm/mach-omap2/board-omap3touchbook.c |8 +++--
 arch/arm/mach-omap2/board-overo.c  |7 +++--
 arch/arm/mach-omap2/board-zoom.c   |5 +--
 arch/arm/mach-omap2/common-board-devices.c |   46 
 arch/arm/mach-omap2/common-board-devices.h |1 -
 arch/arm/mach-omap2/gpmc-onenand.c |   28 -
 arch/arm/mach-omap2/gpmc.c |6 
 arch/arm/mach-omap2/usb-tusb6010.c |3 +-
 arch/arm/plat-omap/include/plat/gpmc.h |6 
 15 files changed, 82 insertions(+), 101 deletions(-)

-- 
1.7.10.2

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


[PATCH v2 1/3] ARM: OMAP2+: nand: unify init functions

2012-06-16 Thread Afzal Mohammed
Helper function for updating nand platform data has been
added the capability to take timing structure arguement.
Usage of omap_nand_flash_init() has been replaced by modifed
one, omap_nand_flash_init was doing things similar to
board_nand_init except that NAND CS# were being acquired
based on bootloader setting. As CS# is hardwired for a given
board, acquiring gpmc CS# has been removed, and updated with
the value on board.

NAND CS# used in beagle board was found to be CS0.
Thomas Weber thomas.weber.li...@googlemail.com reported
that value of devkit8000 to be CS0. Overo board was found
to be using CS0 based on u-boot, while google grep says
omap3touchbook too has CS0.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-devkit8000.c |8 +++--
 arch/arm/mach-omap2/board-flash.c  |   45 ++-
 arch/arm/mach-omap2/board-flash.h  |6 ++--
 arch/arm/mach-omap2/board-igep0020.c   |2 +-
 arch/arm/mach-omap2/board-ldp.c|4 +--
 arch/arm/mach-omap2/board-omap3beagle.c|8 +++--
 arch/arm/mach-omap2/board-omap3touchbook.c |8 +++--
 arch/arm/mach-omap2/board-overo.c  |7 +++--
 arch/arm/mach-omap2/board-zoom.c   |5 +--
 arch/arm/mach-omap2/common-board-devices.c |   46 
 arch/arm/mach-omap2/common-board-devices.h |1 -
 11 files changed, 56 insertions(+), 84 deletions(-)

diff --git a/arch/arm/mach-omap2/board-devkit8000.c 
b/arch/arm/mach-omap2/board-devkit8000.c
index 6567c1c..6ee429a 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -59,8 +59,11 @@
 
 #include mux.h
 #include hsmmc.h
+#include board-flash.h
 #include common-board-devices.h
 
+#defineNAND_CS 0
+
 #define OMAP_DM9000_GPIO_IRQ   25
 #define OMAP3_DEVKIT_TS_GPIO   27
 
@@ -628,8 +631,9 @@ static void __init devkit8000_init(void)
 
usb_musb_init(NULL);
usbhs_init(usbhs_bdata);
-   omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions,
-ARRAY_SIZE(devkit8000_nand_partitions));
+   board_nand_init(devkit8000_nand_partitions,
+   ARRAY_SIZE(devkit8000_nand_partitions), NAND_CS,
+   NAND_BUSWIDTH_16, NULL);
 
/* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal(sdrc_cke0, OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-flash.c 
b/arch/arm/mach-omap2/board-flash.c
index 70a81f9..0ee820b 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -108,41 +108,41 @@ __init board_onenand_init(struct mtd_partition 
*nor_parts, u8 nr_parts, u8 cs)
defined(CONFIG_MTD_NAND_OMAP2_MODULE)
 
 /* Note that all values in this struct are in nanoseconds */
-static struct gpmc_timings nand_timings = {
+struct gpmc_timings nand_default_timings[1] = {
+   {
+   .sync_clk = 0,
 
-   .sync_clk = 0,
+   .cs_on = 0,
+   .cs_rd_off = 36,
+   .cs_wr_off = 36,
 
-   .cs_on = 0,
-   .cs_rd_off = 36,
-   .cs_wr_off = 36,
+   .adv_on = 6,
+   .adv_rd_off = 24,
+   .adv_wr_off = 36,
 
-   .adv_on = 6,
-   .adv_rd_off = 24,
-   .adv_wr_off = 36,
+   .we_off = 30,
+   .oe_off = 48,
 
-   .we_off = 30,
-   .oe_off = 48,
+   .access = 54,
+   .rd_cycle = 72,
+   .wr_cycle = 72,
 
-   .access = 54,
-   .rd_cycle = 72,
-   .wr_cycle = 72,
-
-   .wr_access = 30,
-   .wr_data_mux_bus = 0,
+   .wr_access = 30,
+   .wr_data_mux_bus = 0,
+   },
 };
 
-static struct omap_nand_platform_data board_nand_data = {
-   .gpmc_t = nand_timings,
-};
+static struct omap_nand_platform_data board_nand_data;
 
 void
-__init board_nand_init(struct mtd_partition *nand_parts,
-   u8 nr_parts, u8 cs, int nand_type)
+__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
+   int nand_type, struct gpmc_timings *gpmc_t)
 {
board_nand_data.cs  = cs;
board_nand_data.parts   = nand_parts;
board_nand_data.nr_parts= nr_parts;
board_nand_data.devsize = nand_type;
+   board_nand_data.gpmc_t  = gpmc_t;
 
board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs;
@@ -243,5 +243,6 @@ void __init board_flash_init(struct flash_partitions 
partition_info[],
pr_err(NAND: Unable to find configuration in GPMC\n);
else
board_nand_init(partition_info[2].parts,
-   partition_info[2].nr_parts, nandcs, nand_type);
+   partition_info[2].nr_parts, nandcs,
+   nand_type

[PATCH v2 2/3] ARM: OMAP2+: onenand: prepare for gpmc driver migration

2012-06-16 Thread Afzal Mohammed
Reorganize gpmc-onenand initialization so that changes
required for gpmc driver migration can be made smooth.

Ensuring sync read/write are disabled in onenand cannot
be expected to work properly unless GPMC is setup, this
has been removed. And invocation of set_async has been
moved from set_sync to gpmc_onenand_init function; gpmc
for onenand needs to be initialized to async mode (even
for sync mode initially). Ensuring that onenand part
has been setup for async mode has been moved now to
setup function.

Thanks to Jon for his suggestions on improving this change.

Signed-off-by: Afzal Mohammed af...@ti.com
---

v2: Move ensuring that async mode in OneNAND has been setup from
 set_sync to setup function, improve commit message

 arch/arm/mach-omap2/gpmc-onenand.c |   25 ++---
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c 
b/arch/arm/mach-omap2/gpmc-onenand.c
index 71d7c07..975c1f9 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -38,10 +38,9 @@ static struct platform_device gpmc_onenand_device = {
.resource   = gpmc_onenand_resource,
 };
 
-static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base)
+static int omap2_onenand_set_async_mode(int cs)
 {
struct gpmc_timings t;
-   u32 reg;
int err;
 
const int t_cer = 15;
@@ -55,11 +54,6 @@ static int omap2_onenand_set_async_mode(int cs, void __iomem 
*onenand_base)
const int t_wpl = 40;
const int t_wph = 30;
 
-   /* Ensure sync read and sync write are disabled */
-   reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
-   reg = ~ONENAND_SYS_CFG1_SYNC_READ  ~ONENAND_SYS_CFG1_SYNC_WRITE;
-   writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
-
memset(t, 0, sizeof(t));
t.sync_clk = 0;
t.cs_on = 0;
@@ -95,10 +89,6 @@ static int omap2_onenand_set_async_mode(int cs, void __iomem 
*onenand_base)
if (err)
return err;
 
-   /* Ensure sync read and sync write are disabled */
-   reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
-   reg = ~ONENAND_SYS_CFG1_SYNC_READ  ~ONENAND_SYS_CFG1_SYNC_WRITE;
-   writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
 
return 0;
 }
@@ -197,13 +187,10 @@ static int omap2_onenand_set_sync_mode(struct 
omap_onenand_platform_data *cfg,
sync_read = 1;
sync_write = 1;
} else
-   return omap2_onenand_set_async_mode(cs, onenand_base);
+   return 0;
 
if (!freq) {
/* Very first call freq is not known */
-   err = omap2_onenand_set_async_mode(cs, onenand_base);
-   if (err)
-   return err;
freq = omap2_onenand_get_freq(cfg, onenand_base, clk_dep);
first_time = 1;
}
@@ -385,6 +372,12 @@ static int omap2_onenand_set_sync_mode(struct 
omap_onenand_platform_data *cfg,
 static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr)
 {
struct device *dev = gpmc_onenand_device.dev;
+   u32 reg;
+
+   /* Ensure sync read and sync write are disabled */
+   reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
+   reg = ~ONENAND_SYS_CFG1_SYNC_READ  ~ONENAND_SYS_CFG1_SYNC_WRITE;
+   writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
 
/* Set sync timings in GPMC */
if (omap2_onenand_set_sync_mode(gpmc_onenand_data, onenand_base,
@@ -421,6 +414,8 @@ void __init gpmc_onenand_init(struct 
omap_onenand_platform_data *_onenand_data)
gpmc_onenand_resource.end = gpmc_onenand_resource.start +
ONENAND_IO_SIZE - 1;
 
+   omap2_onenand_set_async_mode(gpmc_onenand_data-cs);
+
if (platform_device_register(gpmc_onenand_device)  0) {
pr_err(%s: Unable to register OneNAND device\n, __func__);
gpmc_cs_free(gpmc_onenand_data-cs);
-- 
1.7.10.2

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


[PATCH v2 3/3] ARM: OMAP2+: gpmc: handle additional timings

2012-06-16 Thread Afzal Mohammed
Configure busturnaround, cycle2cycledelay, waitmonitoringtime,
clkactivationtime in gpmc_cs_set_timings(). This is done so
that boards can configure these parameters of gpmc in Kernel
instead of relying on bootloader.

This needed change to two existing users that were configuring
clk activation time by directly writing to registers. Thanks to
Tony for making me aware of the issue  being kind enough to
test this change.

Signed-off-by: Afzal Mohammed af...@ti.com
---

v2: Make use of timings api for setting clock activation time, and
 remove direct writing to register for clock activation. Peripherals
 making use of it were tusb6010  onenand

 arch/arm/mach-omap2/gpmc-onenand.c |3 ++-
 arch/arm/mach-omap2/gpmc.c |6 ++
 arch/arm/mach-omap2/usb-tusb6010.c |3 ++-
 arch/arm/plat-omap/include/plat/gpmc.h |6 ++
 4 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c 
b/arch/arm/mach-omap2/gpmc-onenand.c
index 975c1f9..476b18c 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -316,6 +316,8 @@ static int omap2_onenand_set_sync_mode(struct 
omap_onenand_platform_data *cfg,
t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div +
 ticks_cez);
 
+   t.clk_activation = fclk_offset_ns;
+
/* Write */
if (sync_write) {
t.adv_wr_off = t.adv_rd_off;
@@ -349,7 +351,6 @@ static int omap2_onenand_set_sync_mode(struct 
omap_onenand_platform_data *cfg,
  (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) |
  (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) |
  (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) |
- GPMC_CONFIG1_CLKACTIVATIONTIME(fclk_offset) |
  GPMC_CONFIG1_PAGE_LEN(2) |
  (cpu_is_omap34xx() ? 0 :
(GPMC_CONFIG1_WAIT_READ_MON |
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 578fd4c..517953f 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -313,6 +313,12 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings 
*t)
 
GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
 
+   GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround);
+   GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycle_delay);
+
+   GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring);
+   GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation);
+
if (cpu_is_omap34xx()) {
GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access);
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c 
b/arch/arm/mach-omap2/usb-tusb6010.c
index db84a46..5c98755 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -174,6 +174,8 @@ static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned 
fclk_ps)
tmp = t.cs_wr_off * 1000 + 7000 /* t_scsn_rdy_z */;
t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
 
+   t.clk_activation = gpmc_ticks_to_ns(1);
+
return gpmc_cs_set_timings(sync_cs, t);
 }
 
@@ -283,7 +285,6 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data 
*data,
| GPMC_CONFIG1_READTYPE_SYNC
| GPMC_CONFIG1_WRITEMULTIPLE_SUPP
| GPMC_CONFIG1_WRITETYPE_SYNC
-   | GPMC_CONFIG1_CLKACTIVATIONTIME(1)
| GPMC_CONFIG1_PAGE_LEN(2)
| GPMC_CONFIG1_WAIT_READ_MON
| GPMC_CONFIG1_WAIT_WRITE_MON
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h 
b/arch/arm/plat-omap/include/plat/gpmc.h
index 2e6e259..802fb22 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -128,6 +128,12 @@ struct gpmc_timings {
u16 rd_cycle;   /* Total read cycle time */
u16 wr_cycle;   /* Total write cycle time */
 
+   u16 bus_turnaround;
+   u16 cycle2cycle_delay;
+
+   u16 wait_monitoring;
+   u16 clk_activation;
+
/* The following are only on OMAP3430 */
u16 wr_access;  /* WRACCESSTIME */
u16 wr_data_mux_bus;/* WRDATAONADMUXBUS */
-- 
1.7.10.2

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


[PATCH v3 0/3] Prepare for GPMC driver conversion

2012-06-21 Thread Afzal Mohammed
Hi,

Objective of this series is to make things easy for GPMC driver
conversion series by separating out more things from driver
conversion series.

This series,
1. Unifies NAND platform initialization functions
2. Prepares OneNAND platform code for gpmc driver migration
3. Handles additional timings in Kernel

This series is based on 3.5-rc1  made on top of
[PATCH v2 00/10] Prepare for GPMC driver conversion (w.r.t MTD)
{http://www.mail-archive.com/linux-omap@vger.kernel.org/msg70096.html}

These changes has been tested with omap3evm  beagle board. Relevant
GPMC peripherals that got tested by this were NAND (beagle) and
OneNAND (using local patches for omap3evm)

Regards
Afzal

v3:
1. Refactor OneNAND set_sync/async functions to separate out timing
 and configurations
2. Handle bool type timings too
3. Swap patches 2  3 due to dependency of OneNAND change on  newly
 added bool type timings
v2:
1. Make use of timing api for setting clock activation time, and
 remove direct writing to register for clock activation. Peripherals
 making use of it were tusb6010  onenand
2. Move ensuring that async mode in OneNAND has been setup from
 set_sync to setup function, improve commit message


Afzal Mohammed (3):
  ARM: OMAP2+: nand: unify init functions
  ARM: OMAP2+: gpmc: handle additional timings
  ARM: OMAP2+: onenand: prepare for gpmc driver migration

 arch/arm/mach-omap2/board-devkit8000.c |8 +-
 arch/arm/mach-omap2/board-flash.c  |   45 -
 arch/arm/mach-omap2/board-flash.h  |6 +-
 arch/arm/mach-omap2/board-igep0020.c   |2 +-
 arch/arm/mach-omap2/board-ldp.c|4 +-
 arch/arm/mach-omap2/board-omap3beagle.c|8 +-
 arch/arm/mach-omap2/board-omap3touchbook.c |8 +-
 arch/arm/mach-omap2/board-overo.c  |7 +-
 arch/arm/mach-omap2/board-zoom.c   |5 +-
 arch/arm/mach-omap2/common-board-devices.c |   46 --
 arch/arm/mach-omap2/common-board-devices.h |1 -
 arch/arm/mach-omap2/gpmc-onenand.c |  137 ++--
 arch/arm/mach-omap2/gpmc.c |   45 +
 arch/arm/mach-omap2/usb-tusb6010.c |3 +-
 arch/arm/plat-omap/include/plat/gpmc.h |   19 
 15 files changed, 193 insertions(+), 151 deletions(-)

-- 
1.7.10.2

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


[PATCH v3 1/3] ARM: OMAP2+: nand: unify init functions

2012-06-21 Thread Afzal Mohammed
Helper function for updating nand platform data has been
added the capability to take timing structure arguement.
Usage of omap_nand_flash_init() has been replaced by modifed
one, omap_nand_flash_init was doing things similar to
board_nand_init except that NAND CS# were being acquired
based on bootloader setting. As CS# is hardwired for a given
board, acquiring gpmc CS# has been removed, and updated with
the value on board.

NAND CS# used in beagle board was found to be CS0.
Thomas Weber thomas.weber.li...@googlemail.com reported
that value of devkit8000 to be CS0. Overo board was found
to be using CS0 based on u-boot, while google grep says
omap3touchbook too has CS0.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-devkit8000.c |8 +++--
 arch/arm/mach-omap2/board-flash.c  |   45 ++-
 arch/arm/mach-omap2/board-flash.h  |6 ++--
 arch/arm/mach-omap2/board-igep0020.c   |2 +-
 arch/arm/mach-omap2/board-ldp.c|4 +--
 arch/arm/mach-omap2/board-omap3beagle.c|8 +++--
 arch/arm/mach-omap2/board-omap3touchbook.c |8 +++--
 arch/arm/mach-omap2/board-overo.c  |7 +++--
 arch/arm/mach-omap2/board-zoom.c   |5 +--
 arch/arm/mach-omap2/common-board-devices.c |   46 
 arch/arm/mach-omap2/common-board-devices.h |1 -
 11 files changed, 56 insertions(+), 84 deletions(-)

diff --git a/arch/arm/mach-omap2/board-devkit8000.c 
b/arch/arm/mach-omap2/board-devkit8000.c
index 6567c1c..6ee429a 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -59,8 +59,11 @@
 
 #include mux.h
 #include hsmmc.h
+#include board-flash.h
 #include common-board-devices.h
 
+#defineNAND_CS 0
+
 #define OMAP_DM9000_GPIO_IRQ   25
 #define OMAP3_DEVKIT_TS_GPIO   27
 
@@ -628,8 +631,9 @@ static void __init devkit8000_init(void)
 
usb_musb_init(NULL);
usbhs_init(usbhs_bdata);
-   omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions,
-ARRAY_SIZE(devkit8000_nand_partitions));
+   board_nand_init(devkit8000_nand_partitions,
+   ARRAY_SIZE(devkit8000_nand_partitions), NAND_CS,
+   NAND_BUSWIDTH_16, NULL);
 
/* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal(sdrc_cke0, OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-flash.c 
b/arch/arm/mach-omap2/board-flash.c
index 70a81f9..0ee820b 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -108,41 +108,41 @@ __init board_onenand_init(struct mtd_partition 
*nor_parts, u8 nr_parts, u8 cs)
defined(CONFIG_MTD_NAND_OMAP2_MODULE)
 
 /* Note that all values in this struct are in nanoseconds */
-static struct gpmc_timings nand_timings = {
+struct gpmc_timings nand_default_timings[1] = {
+   {
+   .sync_clk = 0,
 
-   .sync_clk = 0,
+   .cs_on = 0,
+   .cs_rd_off = 36,
+   .cs_wr_off = 36,
 
-   .cs_on = 0,
-   .cs_rd_off = 36,
-   .cs_wr_off = 36,
+   .adv_on = 6,
+   .adv_rd_off = 24,
+   .adv_wr_off = 36,
 
-   .adv_on = 6,
-   .adv_rd_off = 24,
-   .adv_wr_off = 36,
+   .we_off = 30,
+   .oe_off = 48,
 
-   .we_off = 30,
-   .oe_off = 48,
+   .access = 54,
+   .rd_cycle = 72,
+   .wr_cycle = 72,
 
-   .access = 54,
-   .rd_cycle = 72,
-   .wr_cycle = 72,
-
-   .wr_access = 30,
-   .wr_data_mux_bus = 0,
+   .wr_access = 30,
+   .wr_data_mux_bus = 0,
+   },
 };
 
-static struct omap_nand_platform_data board_nand_data = {
-   .gpmc_t = nand_timings,
-};
+static struct omap_nand_platform_data board_nand_data;
 
 void
-__init board_nand_init(struct mtd_partition *nand_parts,
-   u8 nr_parts, u8 cs, int nand_type)
+__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
+   int nand_type, struct gpmc_timings *gpmc_t)
 {
board_nand_data.cs  = cs;
board_nand_data.parts   = nand_parts;
board_nand_data.nr_parts= nr_parts;
board_nand_data.devsize = nand_type;
+   board_nand_data.gpmc_t  = gpmc_t;
 
board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs;
@@ -243,5 +243,6 @@ void __init board_flash_init(struct flash_partitions 
partition_info[],
pr_err(NAND: Unable to find configuration in GPMC\n);
else
board_nand_init(partition_info[2].parts,
-   partition_info[2].nr_parts, nandcs, nand_type);
+   partition_info[2].nr_parts, nandcs,
+   nand_type

[PATCH v3 2/3] ARM: OMAP2+: gpmc: handle additional timings

2012-06-21 Thread Afzal Mohammed
Configure busturnaround, cycle2cycledelay, waitmonitoringtime,
clkactivationtime in gpmc_cs_set_timings(). This is done so
that boards can configure these parameters of gpmc in Kernel
instead of relying on bootloader. Also configure bool type
timings like extradelay.

This needed change to two existing users that were configuring
clk activation time by directly writing to registers. Thanks to
Tony for making me aware of the issue  being kind enough to
test this change.

Signed-off-by: Afzal Mohammed af...@ti.com
---

v3:
Handle bool type timings too
v2:
Make use of timing api for setting clock activation time, and
 remove direct writing to register for clock activation. Peripherals
 making use of it were tusb6010  onenand

 arch/arm/mach-omap2/gpmc-onenand.c |3 ++-
 arch/arm/mach-omap2/gpmc.c |   45 
 arch/arm/mach-omap2/usb-tusb6010.c |3 ++-
 arch/arm/plat-omap/include/plat/gpmc.h |   19 ++
 4 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c 
b/arch/arm/mach-omap2/gpmc-onenand.c
index 71d7c07..8863e0a 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -329,6 +329,8 @@ static int omap2_onenand_set_sync_mode(struct 
omap_onenand_platform_data *cfg,
t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div +
 ticks_cez);
 
+   t.clk_activation = fclk_offset_ns;
+
/* Write */
if (sync_write) {
t.adv_wr_off = t.adv_rd_off;
@@ -362,7 +364,6 @@ static int omap2_onenand_set_sync_mode(struct 
omap_onenand_platform_data *cfg,
  (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) |
  (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) |
  (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) |
- GPMC_CONFIG1_CLKACTIVATIONTIME(fclk_offset) |
  GPMC_CONFIG1_PAGE_LEN(2) |
  (cpu_is_omap34xx() ? 0 :
(GPMC_CONFIG1_WAIT_READ_MON |
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 578fd4c..8b0978f 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -64,6 +64,13 @@
 #define GPMC_ECC_CTRL_ECCREG8  0x008
 #define GPMC_ECC_CTRL_ECCREG9  0x009
 
+#defineGPMC_CONFIG2_CSEXTRADELAY   BIT(7)
+#defineGPMC_CONFIG3_ADVEXTRADELAY  BIT(7)
+#defineGPMC_CONFIG4_OEEXTRADELAY   BIT(7)
+#defineGPMC_CONFIG4_WEEXTRADELAY   BIT(23)
+#defineGPMC_CONFIG6_CYCLE2CYCLEDIFFCSENBIT(6)
+#defineGPMC_CONFIG6_CYCLE2CYCLESAMECSENBIT(7)
+
 #define GPMC_CS0_OFFSET0x60
 #define GPMC_CS_SIZE   0x30
 
@@ -220,6 +227,36 @@ unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
return ticks * gpmc_get_fclk_period() / 1000;
 }
 
+static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value)
+{
+   u32 l;
+
+   l = gpmc_cs_read_reg(cs, reg);
+   if (value)
+   l |= mask;
+   else
+   l = ~mask;
+   gpmc_cs_write_reg(cs, reg, l);
+}
+
+static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
+{
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG1,
+   GPMC_CONFIG1_TIME_PARA_GRAN, p-time_para_granularity);
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG2,
+   GPMC_CONFIG2_CSEXTRADELAY, p-cs_extra_delay);
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG3,
+   GPMC_CONFIG3_ADVEXTRADELAY, p-adv_extra_delay);
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+   GPMC_CONFIG4_OEEXTRADELAY, p-oe_extra_delay);
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+   GPMC_CONFIG4_OEEXTRADELAY, p-we_extra_delay);
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
+   GPMC_CONFIG6_CYCLE2CYCLESAMECSEN, p-cycle2cyclesamecsen);
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
+   GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN, p-cycle2cyclediffcsen);
+}
+
 #ifdef DEBUG
 static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
   int time, const char *name)
@@ -313,6 +350,12 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings 
*t)
 
GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
 
+   GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround);
+   GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycle_delay);
+
+   GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring);
+   GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation);
+
if (cpu_is_omap34xx()) {
GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access);
@@ -332,6 +375,8 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings 
*t

[PATCH v3 3/3] ARM: OMAP2+: onenand: prepare for gpmc driver migration

2012-06-21 Thread Afzal Mohammed
Reorganize gpmc-onenand initialization so that changes
required for gpmc driver migration can be made smooth.

Ensuring sync read/write are disabled in onenand cannot
be expected to work properly unless GPMC is setup, this
has been removed.

Refactor set_async_mode  set_sync_mode functions to
separate out timing calculation  actual configuration
(GPMC  OneNAND side).

Thanks to Jon for his suggestions.

Signed-off-by: Afzal Mohammed af...@ti.com
---

v3:
Refactor set_sync/async functions to separate out timing and
 configurations
v2:
Move ensuring that async mode in OneNAND has been setup from
 set_sync to setup function, improve commit message

 arch/arm/mach-omap2/gpmc-onenand.c |  134 +++-
 1 file changed, 69 insertions(+), 65 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c 
b/arch/arm/mach-omap2/gpmc-onenand.c
index 8863e0a..789ca8c9 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -15,6 +15,7 @@
 #include linux/platform_device.h
 #include linux/mtd/onenand_regs.h
 #include linux/io.h
+#include linux/err.h
 
 #include asm/mach/flash.h
 
@@ -25,6 +26,7 @@
 
 #defineONENAND_IO_SIZE SZ_128K
 
+static int hf, vhf, sync_read, sync_write, latency;
 static struct omap_onenand_platform_data *gpmc_onenand_data;
 
 static struct resource gpmc_onenand_resource = {
@@ -38,11 +40,9 @@ static struct platform_device gpmc_onenand_device = {
.resource   = gpmc_onenand_resource,
 };
 
-static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base)
+static struct gpmc_timings omap2_onenand_calc_async_timings(void)
 {
struct gpmc_timings t;
-   u32 reg;
-   int err;
 
const int t_cer = 15;
const int t_avdp = 12;
@@ -55,11 +55,6 @@ static int omap2_onenand_set_async_mode(int cs, void __iomem 
*onenand_base)
const int t_wpl = 40;
const int t_wph = 30;
 
-   /* Ensure sync read and sync write are disabled */
-   reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
-   reg = ~ONENAND_SYS_CFG1_SYNC_READ  ~ONENAND_SYS_CFG1_SYNC_WRITE;
-   writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
-
memset(t, 0, sizeof(t));
t.sync_clk = 0;
t.cs_on = 0;
@@ -86,12 +81,21 @@ static int omap2_onenand_set_async_mode(int cs, void 
__iomem *onenand_base)
t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
t.wr_cycle  = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
 
+   return t;
+}
+
+static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base,
+   struct gpmc_timings *t)
+{
+   u32 reg;
+   int err;
+
/* Configure GPMC for asynchronous read */
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
  GPMC_CONFIG1_DEVICESIZE_16 |
  GPMC_CONFIG1_MUXADDDATA);
 
-   err = gpmc_cs_set_timings(cs, t);
+   err = gpmc_cs_set_timings(cs, t);
if (err)
return err;
 
@@ -103,8 +107,7 @@ static int omap2_onenand_set_async_mode(int cs, void 
__iomem *onenand_base)
return 0;
 }
 
-static void set_onenand_cfg(void __iomem *onenand_base, int latency,
-   int sync_read, int sync_write, int hf, int vhf)
+static void set_onenand_cfg(void __iomem *onenand_base)
 {
u32 reg;
 
@@ -172,9 +175,9 @@ static int omap2_onenand_get_freq(struct 
omap_onenand_platform_data *cfg,
return freq;
 }
 
-static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
-   void __iomem *onenand_base,
-   int *freq_ptr)
+static struct gpmc_timings
+omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
+   int freq, bool clk_dep)
 {
struct gpmc_timings t;
const int t_cer  = 15;
@@ -184,28 +187,15 @@ static int omap2_onenand_set_sync_mode(struct 
omap_onenand_platform_data *cfg,
const int t_wpl  = 40;
const int t_wph  = 30;
int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
-   int div, fclk_offset_ns, fclk_offset, gpmc_clk_ns, latency;
-   int first_time = 0, hf = 0, vhf = 0, sync_read = 0, sync_write = 0;
-   int err, ticks_cez;
-   int cs = cfg-cs, freq = *freq_ptr;
-   u32 reg;
-   bool clk_dep = false;
+   int div, fclk_offset_ns, fclk_offset, gpmc_clk_ns;
+   int ticks_cez;
+   int cs = cfg-cs;
 
if (cfg-flags  ONENAND_SYNC_READ) {
sync_read = 1;
} else if (cfg-flags  ONENAND_SYNC_READWRITE) {
sync_read = 1;
sync_write = 1;
-   } else
-   return omap2_onenand_set_async_mode(cs, onenand_base);
-
-   if (!freq) {
-   /* Very first call freq is not known */
-   err = omap2_onenand_set_async_mode(cs

[PATCH v4 0/3] Prepare for GPMC driver conversion

2012-06-22 Thread Afzal Mohammed
Hi,

Objective of this series is to make things easy for GPMC driver
conversion series by separating out more things from driver
conversion series.

This series,
1. Unifies NAND platform initialization functions
2. Prepares OneNAND platform code for gpmc driver migration
3. Handles additional timings in Kernel

This series is based on 3.5-rc1  made on top of
[PATCH v2 00/10] Prepare for GPMC driver conversion (w.r.t MTD)
{http://www.mail-archive.com/linux-omap@vger.kernel.org/msg70096.html}

These changes has been tested with omap3evm  beagle board. Relevant
GPMC peripherals that got tested by this were NAND (beagle) and
OneNAND (using local patches for omap3evm)

Regards
Afzal

v4:
1. Reorganize OneNAND set_sync/async functions in a better way
v3:
1. Refactor OneNAND set_sync/async functions to separate out timing
 and configurations
2. Handle bool type timings too
3. Swap patches 2  3 due to dependency of OneNAND change on  newly
 added bool type timings
v2:
1. Make use of timing api for setting clock activation time, and
 remove direct writing to register for clock activation. Peripherals
 making use of it were tusb6010  onenand
2. Move ensuring that async mode in OneNAND has been setup from
 set_sync to setup function, improve commit message



Afzal Mohammed (3):
  ARM: OMAP2+: nand: unify init functions
  ARM: OMAP2+: gpmc: handle additional timings
  ARM: OMAP2+: onenand: prepare for gpmc driver migration

 arch/arm/mach-omap2/board-devkit8000.c |8 +-
 arch/arm/mach-omap2/board-flash.c  |   45 
 arch/arm/mach-omap2/board-flash.h  |6 +-
 arch/arm/mach-omap2/board-igep0020.c   |2 +-
 arch/arm/mach-omap2/board-ldp.c|4 +-
 arch/arm/mach-omap2/board-omap3beagle.c|8 +-
 arch/arm/mach-omap2/board-omap3touchbook.c |8 +-
 arch/arm/mach-omap2/board-overo.c  |7 +-
 arch/arm/mach-omap2/board-zoom.c   |5 +-
 arch/arm/mach-omap2/common-board-devices.c |   46 
 arch/arm/mach-omap2/common-board-devices.h |1 -
 arch/arm/mach-omap2/gpmc-onenand.c |  156 +++-
 arch/arm/mach-omap2/gpmc.c |   45 
 arch/arm/mach-omap2/usb-tusb6010.c |3 +-
 arch/arm/plat-omap/include/plat/gpmc.h |   19 
 15 files changed, 207 insertions(+), 156 deletions(-)

-- 
1.7.10.2

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


[PATCH v4 1/3] ARM: OMAP2+: nand: unify init functions

2012-06-22 Thread Afzal Mohammed
Helper function for updating nand platform data has been
added the capability to take timing structure arguement.
Usage of omap_nand_flash_init() has been replaced by modifed
one, omap_nand_flash_init was doing things similar to
board_nand_init except that NAND CS# were being acquired
based on bootloader setting. As CS# is hardwired for a given
board, acquiring gpmc CS# has been removed, and updated with
the value on board.

NAND CS# used in beagle board was found to be CS0.
Thomas Weber thomas.weber.li...@googlemail.com reported
that value of devkit8000 to be CS0. Overo board was found
to be using CS0 based on u-boot, while google grep says
omap3touchbook too has CS0.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-devkit8000.c |8 +++--
 arch/arm/mach-omap2/board-flash.c  |   45 ++-
 arch/arm/mach-omap2/board-flash.h  |6 ++--
 arch/arm/mach-omap2/board-igep0020.c   |2 +-
 arch/arm/mach-omap2/board-ldp.c|4 +--
 arch/arm/mach-omap2/board-omap3beagle.c|8 +++--
 arch/arm/mach-omap2/board-omap3touchbook.c |8 +++--
 arch/arm/mach-omap2/board-overo.c  |7 +++--
 arch/arm/mach-omap2/board-zoom.c   |5 +--
 arch/arm/mach-omap2/common-board-devices.c |   46 
 arch/arm/mach-omap2/common-board-devices.h |1 -
 11 files changed, 56 insertions(+), 84 deletions(-)

diff --git a/arch/arm/mach-omap2/board-devkit8000.c 
b/arch/arm/mach-omap2/board-devkit8000.c
index 6567c1c..6ee429a 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -59,8 +59,11 @@
 
 #include mux.h
 #include hsmmc.h
+#include board-flash.h
 #include common-board-devices.h
 
+#defineNAND_CS 0
+
 #define OMAP_DM9000_GPIO_IRQ   25
 #define OMAP3_DEVKIT_TS_GPIO   27
 
@@ -628,8 +631,9 @@ static void __init devkit8000_init(void)
 
usb_musb_init(NULL);
usbhs_init(usbhs_bdata);
-   omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions,
-ARRAY_SIZE(devkit8000_nand_partitions));
+   board_nand_init(devkit8000_nand_partitions,
+   ARRAY_SIZE(devkit8000_nand_partitions), NAND_CS,
+   NAND_BUSWIDTH_16, NULL);
 
/* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal(sdrc_cke0, OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-flash.c 
b/arch/arm/mach-omap2/board-flash.c
index 70a81f9..0ee820b 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -108,41 +108,41 @@ __init board_onenand_init(struct mtd_partition 
*nor_parts, u8 nr_parts, u8 cs)
defined(CONFIG_MTD_NAND_OMAP2_MODULE)
 
 /* Note that all values in this struct are in nanoseconds */
-static struct gpmc_timings nand_timings = {
+struct gpmc_timings nand_default_timings[1] = {
+   {
+   .sync_clk = 0,
 
-   .sync_clk = 0,
+   .cs_on = 0,
+   .cs_rd_off = 36,
+   .cs_wr_off = 36,
 
-   .cs_on = 0,
-   .cs_rd_off = 36,
-   .cs_wr_off = 36,
+   .adv_on = 6,
+   .adv_rd_off = 24,
+   .adv_wr_off = 36,
 
-   .adv_on = 6,
-   .adv_rd_off = 24,
-   .adv_wr_off = 36,
+   .we_off = 30,
+   .oe_off = 48,
 
-   .we_off = 30,
-   .oe_off = 48,
+   .access = 54,
+   .rd_cycle = 72,
+   .wr_cycle = 72,
 
-   .access = 54,
-   .rd_cycle = 72,
-   .wr_cycle = 72,
-
-   .wr_access = 30,
-   .wr_data_mux_bus = 0,
+   .wr_access = 30,
+   .wr_data_mux_bus = 0,
+   },
 };
 
-static struct omap_nand_platform_data board_nand_data = {
-   .gpmc_t = nand_timings,
-};
+static struct omap_nand_platform_data board_nand_data;
 
 void
-__init board_nand_init(struct mtd_partition *nand_parts,
-   u8 nr_parts, u8 cs, int nand_type)
+__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
+   int nand_type, struct gpmc_timings *gpmc_t)
 {
board_nand_data.cs  = cs;
board_nand_data.parts   = nand_parts;
board_nand_data.nr_parts= nr_parts;
board_nand_data.devsize = nand_type;
+   board_nand_data.gpmc_t  = gpmc_t;
 
board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs;
@@ -243,5 +243,6 @@ void __init board_flash_init(struct flash_partitions 
partition_info[],
pr_err(NAND: Unable to find configuration in GPMC\n);
else
board_nand_init(partition_info[2].parts,
-   partition_info[2].nr_parts, nandcs, nand_type);
+   partition_info[2].nr_parts, nandcs,
+   nand_type

[PATCH v4 2/3] ARM: OMAP2+: gpmc: handle additional timings

2012-06-22 Thread Afzal Mohammed
Configure busturnaround, cycle2cycledelay, waitmonitoringtime,
clkactivationtime in gpmc_cs_set_timings(). This is done so
that boards can configure these parameters of gpmc in Kernel
instead of relying on bootloader. Also configure bool type
timings like extradelay.

This needed change to two existing users that were configuring
clk activation time by directly writing to registers. Thanks to
Tony for making me aware of the issue  being kind enough to
test this change.

Signed-off-by: Afzal Mohammed af...@ti.com
---

v3:
Handle bool type timings too
v2:
Make use of timing api for setting clock activation time, and
 remove direct writing to register for clock activation. Peripherals
 making use of it were tusb6010  onenand

 arch/arm/mach-omap2/gpmc-onenand.c |3 ++-
 arch/arm/mach-omap2/gpmc.c |   45 
 arch/arm/mach-omap2/usb-tusb6010.c |3 ++-
 arch/arm/plat-omap/include/plat/gpmc.h |   19 ++
 4 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c 
b/arch/arm/mach-omap2/gpmc-onenand.c
index 71d7c07..8863e0a 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -329,6 +329,8 @@ static int omap2_onenand_set_sync_mode(struct 
omap_onenand_platform_data *cfg,
t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div +
 ticks_cez);
 
+   t.clk_activation = fclk_offset_ns;
+
/* Write */
if (sync_write) {
t.adv_wr_off = t.adv_rd_off;
@@ -362,7 +364,6 @@ static int omap2_onenand_set_sync_mode(struct 
omap_onenand_platform_data *cfg,
  (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) |
  (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) |
  (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) |
- GPMC_CONFIG1_CLKACTIVATIONTIME(fclk_offset) |
  GPMC_CONFIG1_PAGE_LEN(2) |
  (cpu_is_omap34xx() ? 0 :
(GPMC_CONFIG1_WAIT_READ_MON |
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 578fd4c..8b0978f 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -64,6 +64,13 @@
 #define GPMC_ECC_CTRL_ECCREG8  0x008
 #define GPMC_ECC_CTRL_ECCREG9  0x009
 
+#defineGPMC_CONFIG2_CSEXTRADELAY   BIT(7)
+#defineGPMC_CONFIG3_ADVEXTRADELAY  BIT(7)
+#defineGPMC_CONFIG4_OEEXTRADELAY   BIT(7)
+#defineGPMC_CONFIG4_WEEXTRADELAY   BIT(23)
+#defineGPMC_CONFIG6_CYCLE2CYCLEDIFFCSENBIT(6)
+#defineGPMC_CONFIG6_CYCLE2CYCLESAMECSENBIT(7)
+
 #define GPMC_CS0_OFFSET0x60
 #define GPMC_CS_SIZE   0x30
 
@@ -220,6 +227,36 @@ unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
return ticks * gpmc_get_fclk_period() / 1000;
 }
 
+static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value)
+{
+   u32 l;
+
+   l = gpmc_cs_read_reg(cs, reg);
+   if (value)
+   l |= mask;
+   else
+   l = ~mask;
+   gpmc_cs_write_reg(cs, reg, l);
+}
+
+static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
+{
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG1,
+   GPMC_CONFIG1_TIME_PARA_GRAN, p-time_para_granularity);
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG2,
+   GPMC_CONFIG2_CSEXTRADELAY, p-cs_extra_delay);
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG3,
+   GPMC_CONFIG3_ADVEXTRADELAY, p-adv_extra_delay);
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+   GPMC_CONFIG4_OEEXTRADELAY, p-oe_extra_delay);
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+   GPMC_CONFIG4_OEEXTRADELAY, p-we_extra_delay);
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
+   GPMC_CONFIG6_CYCLE2CYCLESAMECSEN, p-cycle2cyclesamecsen);
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
+   GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN, p-cycle2cyclediffcsen);
+}
+
 #ifdef DEBUG
 static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
   int time, const char *name)
@@ -313,6 +350,12 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings 
*t)
 
GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
 
+   GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround);
+   GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycle_delay);
+
+   GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring);
+   GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation);
+
if (cpu_is_omap34xx()) {
GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access);
@@ -332,6 +375,8 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings 
*t

[PATCH v4 3/3] ARM: OMAP2+: onenand: prepare for gpmc driver migration

2012-06-22 Thread Afzal Mohammed
Reorganize gpmc-onenand initialization so that changes
required for gpmc driver migration can be made smooth.

Ensuring sync read/write are disabled in onenand cannot
be expected to work properly unless GPMC is setup, this
has been removed.

Refactor set_async_mode  set_sync_mode functions to
separate out timing calculation  actual configuration
(GPMC  OneNAND side).

Thanks to Jon for his suggestions.

Signed-off-by: Afzal Mohammed af...@ti.com
---

v4:
Reorganize set_sync/async functions in a better way
v3:
Refactor set_sync/async functions to separate out timing and
 configurations
v2:
Move ensuring that async mode in OneNAND has been setup from
 set_sync to setup function, improve commit message

 arch/arm/mach-omap2/gpmc-onenand.c |  153 +++-
 1 file changed, 83 insertions(+), 70 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c 
b/arch/arm/mach-omap2/gpmc-onenand.c
index 8863e0a..878182b 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -15,6 +15,7 @@
 #include linux/platform_device.h
 #include linux/mtd/onenand_regs.h
 #include linux/io.h
+#include linux/err.h
 
 #include asm/mach/flash.h
 
@@ -25,6 +26,7 @@
 
 #defineONENAND_IO_SIZE SZ_128K
 
+static int hf, vhf, sync_read, sync_write, latency;
 static struct omap_onenand_platform_data *gpmc_onenand_data;
 
 static struct resource gpmc_onenand_resource = {
@@ -38,11 +40,9 @@ static struct platform_device gpmc_onenand_device = {
.resource   = gpmc_onenand_resource,
 };
 
-static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base)
+static struct gpmc_timings omap2_onenand_calc_async_timings(void)
 {
struct gpmc_timings t;
-   u32 reg;
-   int err;
 
const int t_cer = 15;
const int t_avdp = 12;
@@ -55,11 +55,6 @@ static int omap2_onenand_set_async_mode(int cs, void __iomem 
*onenand_base)
const int t_wpl = 40;
const int t_wph = 30;
 
-   /* Ensure sync read and sync write are disabled */
-   reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
-   reg = ~ONENAND_SYS_CFG1_SYNC_READ  ~ONENAND_SYS_CFG1_SYNC_WRITE;
-   writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
-
memset(t, 0, sizeof(t));
t.sync_clk = 0;
t.cs_on = 0;
@@ -86,25 +81,30 @@ static int omap2_onenand_set_async_mode(int cs, void 
__iomem *onenand_base)
t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
t.wr_cycle  = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
 
+   return t;
+}
+
+static int gpmc_set_async_mode(int cs, struct gpmc_timings *t)
+{
/* Configure GPMC for asynchronous read */
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
  GPMC_CONFIG1_DEVICESIZE_16 |
  GPMC_CONFIG1_MUXADDDATA);
 
-   err = gpmc_cs_set_timings(cs, t);
-   if (err)
-   return err;
+   return gpmc_cs_set_timings(cs, t);
+}
+
+static void omap2_onenand_set_async_mode(void __iomem *onenand_base)
+{
+   u32 reg;
 
/* Ensure sync read and sync write are disabled */
reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
reg = ~ONENAND_SYS_CFG1_SYNC_READ  ~ONENAND_SYS_CFG1_SYNC_WRITE;
writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
-
-   return 0;
 }
 
-static void set_onenand_cfg(void __iomem *onenand_base, int latency,
-   int sync_read, int sync_write, int hf, int vhf)
+static void set_onenand_cfg(void __iomem *onenand_base)
 {
u32 reg;
 
@@ -172,9 +172,9 @@ static int omap2_onenand_get_freq(struct 
omap_onenand_platform_data *cfg,
return freq;
 }
 
-static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
-   void __iomem *onenand_base,
-   int *freq_ptr)
+static struct gpmc_timings
+omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
+   int freq, bool clk_dep)
 {
struct gpmc_timings t;
const int t_cer  = 15;
@@ -184,28 +184,15 @@ static int omap2_onenand_set_sync_mode(struct 
omap_onenand_platform_data *cfg,
const int t_wpl  = 40;
const int t_wph  = 30;
int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
-   int div, fclk_offset_ns, fclk_offset, gpmc_clk_ns, latency;
-   int first_time = 0, hf = 0, vhf = 0, sync_read = 0, sync_write = 0;
-   int err, ticks_cez;
-   int cs = cfg-cs, freq = *freq_ptr;
-   u32 reg;
-   bool clk_dep = false;
+   int div, fclk_offset_ns, fclk_offset, gpmc_clk_ns;
+   int ticks_cez;
+   int cs = cfg-cs;
 
if (cfg-flags  ONENAND_SYNC_READ) {
sync_read = 1;
} else if (cfg-flags  ONENAND_SYNC_READWRITE) {
sync_read = 1;
sync_write = 1;
-   } else
-   return

[PATCH v6 00/13] GPMC driver conversion

2012-06-22 Thread Afzal Mohammed
Hi,

This series is based on 3.5-rc1, and is dependent on [1,2,3], and has
been tested on omap3evm (smsc911x) rev G  C and beagle board(nand).
Also using private patches, nand  onenand was tested on omap3evm,
rev G  C respectively (as support for these were not in mainline)

All boards will work using the old existing interface. Further patch
series would convert all boards to use new interface.

Many of GPMC peripherals depend on bootloader for configuration.
This is going to be deprecated. feature-removal-schedule.txt will be
updated in one of the upcoming patch series.

Thanks to Tony  Jon for their various suggestions.

[PATCH 03/13] ARM: OMAP2+: gpmc: driver migration helper, is to be
reverted once all GPMC peripherals are migrated to use driver
interface.

GPMC (General Purpose Memory Controller) in brief:
GPMC is an unified memory controller dedicated to interfacing external
memory devices like
 Asynchronous SRAM like memories and application specific integrated circuit 
devices.
 Asynchronous, synchronous, and page mode burst NOR flash devices NAND flash
 Pseudo-SRAM devices

GPMC details can be referred in AM335X Technical Reference Manual
@ http://www.ti.com/lit/pdf/spruh73

Regards
Afzal

[1] http://www.mail-archive.com/linux-omap@vger.kernel.org/msg70096.html
[2] http://www.mail-archive.com/linux-omap@vger.kernel.org/msg70730.html
[3] http://www.mail-archive.com/linux-omap@vger.kernel.org/msg69881.html

v6: Capability flag added that stores features based on revision
Macros used for finding revision
Return value from memory setup function corrected
Comments added to clarify handling of device type, size
Bool type time setting patch removed as has been taken care in [2]
Handle variable number of waitpin
Warn if driver is unable to configure interrupt
Enhance some of commit messages
Handle shared writeprotect case
Fix a bug in gpmc_create_device
Get clk from hwmod
Remove unwanted code
v5: Make this a purely driver conversion series, i.e. gpmc-mtd
interactions has been made as a separate series, so is adding
hwmod entry for OMAP2/3.
And modifying gpmc peripheral platform initialization has been
separated out of this series, so is migrating boards to use new
driver interface. GPMC driver conversion which was done in a few
patches in v4 has been tranformed to series of small patches.
Also care has been taken care that old interface will not break
with any of these patches, so both interfaces can coexist.
This helps in converting boards one-by-one gradually. Acquiring
CS has been thrown out. And conclusive comments on v4 has been
addressed.
v4: Handle wait pin (except for interrupts), enhance configuration
 timing interface of GPMC to take care of all boards. Dynamic
allocation of interrupt instead of static. Convert remaining
peripherals to work with GPMC driver. Handle acquiring NAND CS#,
adapt to HWMOD, update HWMOD OMAP2/3 entries, other minor
commenst on v3.
v3: Single device structure passed from platform for peripherals using
multiple CS instead of using multiple device structure having a few
redundant data, handle interrupts, GPMC NAND handling by GPMC NAND
driver instead of GPMC driver
v2: Avoid code movement that kept similar code together (for easy review)


Afzal Mohammed (13):
  ARM: OMAP2+: gpmc: platform definitions
  ARM: OMAP2+: gpmc: Adapt to HWMOD
  ARM: OMAP2+: gpmc: driver migration helper
  ARM: OMAP2+: gpmc: minimal driver support
  ARM: OMAP2+: gpmc: resource creation helpers
  ARM: OMAP2+: gpmc: CS configuration helper
  ARM: OMAP2+: gpmc: register time setting helper
  ARM: OMAP2+: gpmc: holler if no configuration
  ARM: OMAP2+: gpmc: waitpin helper
  ARM: OMAP2+: gpmc: handle connected peripherals
  ARM: OMAP2+: gpmc: cs reconfigure helper
  ARM: OMAP2+: gpmc: update nand register info
  ARM: OMAP2+: gpmc: configure writeprotect

 arch/arm/mach-omap2/gpmc.c |  797 ++--
 arch/arm/plat-omap/include/plat/gpmc.h |   58 +++
 2 files changed, 812 insertions(+), 43 deletions(-)

-- 
1.7.10.2

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


[PATCH v6 01/13] ARM: OMAP2+: gpmc: platform definitions

2012-06-22 Thread Afzal Mohammed
gpmc driver platform definitions

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/plat-omap/include/plat/gpmc.h |   37 
 1 file changed, 37 insertions(+)

diff --git a/arch/arm/plat-omap/include/plat/gpmc.h 
b/arch/arm/plat-omap/include/plat/gpmc.h
index b7c9ea6..4e799b1 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -152,6 +152,43 @@ struct gpmc_timings {
struct gpmc_bool_timings bool_timings;
 };
 
+enum {
+   has_none,
+   has_period,
+   has_clock
+};
+
+struct gpmc_time_ctrl {
+   int type;
+   struct gpmc_timings timings;
+};
+
+struct gpmc_cs_data {
+   unsignedcs;
+   unsigned long   mem_size;
+   unsigned long   mem_offset;
+   boolhave_config;
+   unsignedconfig;
+   struct gpmc_time_ctrl   time_ctrl;
+   unsignedirq_config;
+};
+
+struct gpmc_device_pdata {
+   char*name;
+   int id;
+   void*pdata;
+   unsignedpdata_size;
+   struct resource *per_res;
+   unsignedper_res_cnt;
+   struct gpmc_cs_data *cs_data;
+   unsignednum_cs;
+};
+
+struct gpmc_pdata {
+   unsignedwaitpin_nr;
+   struct gpmc_device_pdata**device_pdata;
+};
+
 struct gpmc_nand_regs {
void __iomem*gpmc_status;
void __iomem*gpmc_nand_command;
-- 
1.7.10.2

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


[PATCH v6 02/13] ARM: OMAP2+: gpmc: Adapt to HWMOD

2012-06-22 Thread Afzal Mohammed
Create API for platforms to adapt gpmc to HWMOD

gpmc clk is stored as timing calculation for
platform code require its rate so that GPMC
timing values (platform data for gpmc driver)
can be calculated.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |   31 +++
 arch/arm/plat-omap/include/plat/gpmc.h |2 ++
 2 files changed, 33 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 8b0978f..f8131f8 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -27,6 +27,7 @@
 
 #include asm/mach-types.h
 #include plat/gpmc.h
+#include plat/omap_device.h
 
 #include plat/sdrc.h
 
@@ -937,6 +938,36 @@ static int __init gpmc_init(void)
 }
 postcore_initcall(gpmc_init);
 
+__init int omap_gpmc_init(struct gpmc_pdata *pdata)
+{
+   struct omap_hwmod *oh;
+   struct platform_device *pdev;
+   char *name = omap-gpmc;
+   char *oh_name = gpmc;
+
+   oh = omap_hwmod_lookup(oh_name);
+   if (!oh) {
+   pr_err(Could not look up %s\n, oh_name);
+   return -ENODEV;
+   }
+
+   gpmc_l3_clk = oh-_clk;
+   if (!gpmc_l3_clk) {
+   pr_err(Could not get GPMC clock\n);
+   return -EINVAL;
+   }
+
+   pdev = omap_device_build(name, -1, oh, pdata,
+   sizeof(*pdata), NULL, 0, 0);
+   if (IS_ERR(pdev)) {
+   WARN(1, Can't build omap_device for %s:%s.\n,
+   name, oh-name);
+   return PTR_ERR(pdev);
+   }
+
+   return 0;
+}
+
 static irqreturn_t gpmc_handle_irq(int irq, void *dev)
 {
int i;
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h 
b/arch/arm/plat-omap/include/plat/gpmc.h
index 4e799b1..157753ab 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -208,6 +208,8 @@ struct gpmc_nand_regs {
 extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
 extern int gpmc_get_client_irq(unsigned irq_config);
 
+extern int omap_gpmc_init(struct gpmc_pdata *pdata);
+
 extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
 extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps);
 extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
-- 
1.7.10.2

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


[PATCH v6 03/13] ARM: OMAP2+: gpmc: driver migration helper

2012-06-22 Thread Afzal Mohammed
A driver is being created out of GPMC code. This is being
attempted to acheive by not breaking existing interface,
necessitating requirement of GPMC peripherals being able
to work with using new interface as well as with the old
existing interface. To not break existing, initcall is
required as in old interface GPMC is configured at arch
initcall and GPMC should be ready to handle old interface
by that time

Note: This commit has to be reverted once all boards have
been converted to work with gpmc driver interface

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |   18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index f8131f8..f64f55a 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -941,7 +941,7 @@ postcore_initcall(gpmc_init);
 __init int omap_gpmc_init(struct gpmc_pdata *pdata)
 {
struct omap_hwmod *oh;
-   struct platform_device *pdev;
+   static struct platform_device *pdev;
char *name = omap-gpmc;
char *oh_name = gpmc;
 
@@ -951,6 +951,11 @@ __init int omap_gpmc_init(struct gpmc_pdata *pdata)
return -ENODEV;
}
 
+   if (pdev != NULL) {
+   omap_device_delete(pdev-archdata.od);
+   platform_device_unregister(pdev);
+   }
+
gpmc_l3_clk = oh-_clk;
if (!gpmc_l3_clk) {
pr_err(Could not get GPMC clock\n);
@@ -968,6 +973,17 @@ __init int omap_gpmc_init(struct gpmc_pdata *pdata)
return 0;
 }
 
+static int __init gpmc_pre_init(void)
+{
+   static struct gpmc_device_pdata *gpmc_device_data[1];
+   struct gpmc_pdata gpmc_data = {
+   .device_pdata   = gpmc_device_data,
+   };
+
+   return omap_gpmc_init(gpmc_data);
+}
+postcore_initcall(gpmc_pre_init);
+
 static irqreturn_t gpmc_handle_irq(int irq, void *dev)
 {
int i;
-- 
1.7.10.2

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


[PATCH v6 04/13] ARM: OMAP2+: gpmc: minimal driver support

2012-06-22 Thread Afzal Mohammed
Create a minimal driver out of gpmc code.
Responsibilities handled by earlier gpmc
initialization is now achieved in probe.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |  179 
 1 file changed, 132 insertions(+), 47 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index f64f55a..08fc5df 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -24,6 +24,7 @@
 #include linux/io.h
 #include linux/module.h
 #include linux/interrupt.h
+#include linux/platform_device.h
 
 #include asm/mach-types.h
 #include plat/gpmc.h
@@ -31,6 +32,8 @@
 
 #include plat/sdrc.h
 
+#defineDRIVER_NAME omap-gpmc
+
 /* GPMC register offsets */
 #define GPMC_REVISION  0x00
 #define GPMC_SYSCONFIG 0x10
@@ -86,6 +89,12 @@
 #define ENABLE_PREFETCH(0x1  7)
 #define DMA_MPU_MODE   2
 
+#defineGPMC_REVISION_MAJOR(l)  ((l  4)  0xf)
+#defineGPMC_REVISION_MINOR(l)  (l  0xf)
+
+#defineGPMC_HAS_WR_ACCESS  0x1
+#defineGPMC_HAS_WR_DATA_MUX_BUS0x2
+
 /* XXX: Only NAND irq has been considered,currently these are the only ones 
used
  */
 #defineGPMC_NR_IRQ 2
@@ -122,6 +131,21 @@ struct omap3_gpmc_regs {
struct gpmc_cs_config cs_context[GPMC_CS_NUM];
 };
 
+struct gpmc_peripheral {
+   char*name;
+   int id;
+   void*pdata;
+   unsignedpdata_size;
+   struct resource *per_res;
+   unsignedper_res_cnt;
+   struct resource *gpmc_res;
+   unsignedgpmc_res_cnt;
+   boolhave_waitpin;
+   boolwaitpin_high;
+   unsignedwaitpin;
+   struct platform_device  *pdev;
+};
+
 static struct gpmc_client_irq gpmc_client_irq[GPMC_NR_IRQ];
 static struct irq_chip gpmc_irq_chip;
 static unsigned gpmc_irq_start;
@@ -131,6 +155,10 @@ static struct resource gpmc_cs_mem[GPMC_CS_NUM];
 static DEFINE_SPINLOCK(gpmc_mem_lock);
 static unsigned int gpmc_cs_map;   /* flag for cs which are initialized */
 static int gpmc_ecc_used = -EINVAL;/* cs using ecc engine */
+static struct device *gpmc_dev;
+static u32 gpmc_capability;
+static int gpmc_irq;
+static resource_size_t phys_base, mem_size;
 
 static void __iomem *gpmc_base;
 
@@ -472,6 +500,19 @@ static int gpmc_cs_insert_mem(int cs, unsigned long base, 
unsigned long size)
return r;
 }
 
+static int gpmc_cs_delete_mem(int cs)
+{
+   struct resource *res = gpmc_cs_mem[cs];
+   int r;
+
+   spin_lock(gpmc_mem_lock);
+   r = release_resource(gpmc_cs_mem[cs]);
+   res-start = res-end = 0;
+   spin_unlock(gpmc_mem_lock);
+
+   return r;
+}
+
 int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
 {
struct resource *res = gpmc_cs_mem[cs];
@@ -808,7 +849,7 @@ static void gpmc_irq_noop(struct irq_data *data) { }
 
 static unsigned int gpmc_irq_noop_ret(struct irq_data *data) { return 0; }
 
-static int gpmc_setup_irq(int gpmc_irq)
+static int gpmc_setup_irq(void)
 {
int i;
u32 regval;
@@ -852,7 +893,37 @@ static int gpmc_setup_irq(int gpmc_irq)
return request_irq(gpmc_irq, gpmc_handle_irq, 0, gpmc, NULL);
 }
 
-static void __init gpmc_mem_init(void)
+static __exit int gpmc_free_irq(void)
+{
+   int i;
+
+   if (gpmc_irq)
+   free_irq(gpmc_irq, NULL);
+
+   for (i = 0; i  GPMC_NR_IRQ; i++) {
+   irq_set_handler(gpmc_client_irq[i].irq, NULL);
+   irq_set_chip(gpmc_client_irq[i].irq, no_irq_chip);
+   irq_modify_status(gpmc_client_irq[i].irq, 0, 0);
+   }
+
+   irq_free_descs(gpmc_irq_start, GPMC_NR_IRQ);
+
+   return 0;
+}
+
+static void __devexit gpmc_mem_exit(void)
+{
+   int cs;
+
+   for (cs = 0; cs  GPMC_CS_NUM; cs++) {
+   if (!gpmc_cs_mem_enabled(cs))
+   continue;
+   gpmc_cs_delete_mem(cs);
+   }
+
+}
+
+static void __devinit gpmc_mem_init(void)
 {
int cs;
unsigned long boot_rom_space = 0;
@@ -879,64 +950,78 @@ static void __init gpmc_mem_init(void)
}
 }
 
-static int __init gpmc_init(void)
+static __devinit int gpmc_probe(struct platform_device *pdev)
 {
u32 l;
-   int ret = -EINVAL;
-   int gpmc_irq;
-   char *ck = NULL;
-
-   if (cpu_is_omap24xx()) {
-   ck = core_l3_ck;
-   if (cpu_is_omap2420())
-   l = OMAP2420_GPMC_BASE;
-   else
-   l = OMAP34XX_GPMC_BASE;
-   gpmc_irq = INT_34XX_GPMC_IRQ;
-   } else if (cpu_is_omap34xx()) {
-   ck = gpmc_fck;
-   l = OMAP34XX_GPMC_BASE;
-   gpmc_irq = INT_34XX_GPMC_IRQ;
-   } else

[PATCH v6 05/13] ARM: OMAP2+: gpmc: resource creation helpers

2012-06-22 Thread Afzal Mohammed
Helpers for populating given resource structure
with memory  interrupt information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |   45 
 1 file changed, 45 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 08fc5df..e427ff4 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -950,6 +950,51 @@ static void __devinit gpmc_mem_init(void)
}
 }
 
+static __devinit int gpmc_setup_cs_mem(struct gpmc_cs_data *cs,
+   struct resource *res)
+{
+   unsigned long start;
+   int ret;
+
+   ret = gpmc_cs_request(cs-cs, cs-mem_size, start);
+   if (IS_ERR_VALUE(ret)) {
+   dev_err(gpmc_dev, error: gpmc request on CS: %d\n, cs-cs);
+   return ret;
+   }
+
+   res-start = start + cs-mem_offset;
+   res-end = res-start + cs-mem_size - 1;
+   res-flags = IORESOURCE_MEM;
+
+   dev_info(gpmc_dev, memory 0x%x-0x%x on CS %d\n, res-start,
+   res-end, cs-cs);
+
+   return 0;
+}
+
+static __devinit int gpmc_setup_cs_irq(struct gpmc_cs_data *cs,
+   struct resource *res)
+{
+   int i, n;
+
+   if (!gpmc_irq || !gpmc_irq_start) {
+   if (cs-irq_config)
+   dev_err(gpmc_dev, gpmc not able to configure irq\n);
+   return 0;
+   }
+
+   for (i = 0, n = 0; i  GPMC_NR_IRQ; i++)
+   if (gpmc_client_irq[i].bitmask  cs-irq_config) {
+   res[n].start = res[n].end = gpmc_client_irq[i].irq;
+   res[n].flags = IORESOURCE_IRQ;
+   dev_info(gpmc_dev, irq %u on CS %d\n,
+   res[n].start, cs-cs);
+   n++;
+   }
+
+   return n;
+}
+
 static __devinit int gpmc_probe(struct platform_device *pdev)
 {
u32 l;
-- 
1.7.10.2

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


[PATCH v6 06/13] ARM: OMAP2+: gpmc: CS configuration helper

2012-06-22 Thread Afzal Mohammed
Helper for configuring given CS based on flags.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |   39 
 arch/arm/plat-omap/include/plat/gpmc.h |5 
 2 files changed, 44 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index e427ff4..8f596ce 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -972,6 +972,45 @@ static __devinit int gpmc_setup_cs_mem(struct gpmc_cs_data 
*cs,
return 0;
 }
 
+static void gpmc_setup_cs_config(unsigned cs, unsigned conf)
+{
+   u32 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+   l = ~(GPMC_CONFIG1_MUXADDDATA |
+   GPMC_CONFIG1_WRITETYPE_SYNC |
+   GPMC_CONFIG1_WRITEMULTIPLE_SUPP |
+   GPMC_CONFIG1_READTYPE_SYNC |
+   GPMC_CONFIG1_READMULTIPLE_SUPP |
+   GPMC_CONFIG1_WRAPBURST_SUPP |
+   GPMC_CONFIG1_DEVICETYPE(~0) |
+   GPMC_CONFIG1_DEVICESIZE(~0) |
+   GPMC_CONFIG1_PAGE_LEN(~0));
+
+   /* device type  size bits are cleared above, implying NOR  8 bit,
+* only other options possible are NAND  16 bit respectively,
+* configure if user asked for it, else default is already setup
+* users has been provided with NOR  8 bit macros, nothing to be
+* done here as already it has been setup above
+*/
+   l |= conf  GPMC_CONFIG1_DEVICETYPE_NAND;
+   l |= conf  GPMC_CONFIG1_DEVICESIZE_16;
+
+   if (conf  GPMC_CONFIG1_PAGE_LEN_8)
+   l |= GPMC_CONFIG1_PAGE_LEN_8;
+   else if (conf  GPMC_CONFIG1_PAGE_LEN_16)
+   l |= GPMC_CONFIG1_PAGE_LEN_16;
+
+   conf = (GPMC_CONFIG1_MUXADDDATA |
+   GPMC_CONFIG1_WRITETYPE_SYNC |
+   GPMC_CONFIG1_WRITEMULTIPLE_SUPP |
+   GPMC_CONFIG1_READTYPE_SYNC |
+   GPMC_CONFIG1_READMULTIPLE_SUPP |
+   GPMC_CONFIG1_WRAPBURST_SUPP);
+   l |= conf;
+
+   gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l);
+}
+
 static __devinit int gpmc_setup_cs_irq(struct gpmc_cs_data *cs,
struct resource *res)
 {
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h 
b/arch/arm/plat-omap/include/plat/gpmc.h
index 157753ab..7187445 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -57,14 +57,19 @@
 #define GPMC_CONFIG1_WRITETYPE_SYNC (1  27)
 #define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val  3)  25)
 #define GPMC_CONFIG1_PAGE_LEN(val)  ((val  3)  23)
+#defineGPMC_CONFIG1_PAGE_LEN_4 GPMC_CONFIG1_PAGE_LEN(0)
+#defineGPMC_CONFIG1_PAGE_LEN_8 GPMC_CONFIG1_PAGE_LEN(1)
+#defineGPMC_CONFIG1_PAGE_LEN_16GPMC_CONFIG1_PAGE_LEN(2)
 #define GPMC_CONFIG1_WAIT_READ_MON  (1  22)
 #define GPMC_CONFIG1_WAIT_WRITE_MON (1  21)
 #define GPMC_CONFIG1_WAIT_MON_IIME(val) ((val  3)  18)
 #define GPMC_CONFIG1_WAIT_PIN_SEL(val)  ((val  3)  16)
 #define GPMC_CONFIG1_DEVICESIZE(val)((val  3)  12)
+#defineGPMC_CONFIG1_DEVICESIZE_8   GPMC_CONFIG1_DEVICESIZE(0)
 #define GPMC_CONFIG1_DEVICESIZE_16  GPMC_CONFIG1_DEVICESIZE(1)
 #define GPMC_CONFIG1_DEVICETYPE(val)((val  3)  10)
 #define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0)
+#defineGPMC_CONFIG1_DEVICETYPE_NANDGPMC_CONFIG1_DEVICETYPE(2)
 #define GPMC_CONFIG1_MUXADDDATA (1  9)
 #define GPMC_CONFIG1_TIME_PARA_GRAN (1  4)
 #define GPMC_CONFIG1_FCLK_DIV(val)  (val  3)
-- 
1.7.10.2

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


[PATCH v6 07/13] ARM: OMAP2+: gpmc: register time setting helper

2012-06-22 Thread Afzal Mohammed
Helper for setting GPMC timing by taking input as register values.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |   45 
 1 file changed, 45 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 8f596ce..1998285 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1011,6 +1011,51 @@ static void gpmc_setup_cs_config(unsigned cs, unsigned 
conf)
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l);
 }
 
+static inline void gpmc_set_one_timing(int cs, int reg, int start,
+   int end, u32 val)
+{
+   u32 l;
+   unsigned mask;
+
+   mask = (1  (end - start + 1)) - 1;
+   l = gpmc_cs_read_reg(cs, reg);
+   l = ~(mask  start);
+   l |= val  start;
+   gpmc_cs_write_reg(cs, reg, l);
+}
+
+static void gpmc_cs_set_register_timings(int cs, const struct gpmc_timings *t)
+{
+   gpmc_set_one_timing(cs, GPMC_CS_CONFIG1, 0, 1, t-sync_clk);
+   gpmc_set_one_timing(cs, GPMC_CS_CONFIG1, 18, 19, t-wait_monitoring);
+   gpmc_set_one_timing(cs, GPMC_CS_CONFIG1, 25, 26, t-clk_activation);
+
+   gpmc_set_one_timing(cs, GPMC_CS_CONFIG2, 0, 3, t-cs_on);
+   gpmc_set_one_timing(cs, GPMC_CS_CONFIG2, 8, 12, t-cs_rd_off);
+   gpmc_set_one_timing(cs, GPMC_CS_CONFIG2, 16, 20, t-cs_wr_off);
+
+   gpmc_set_one_timing(cs, GPMC_CS_CONFIG3, 0, 3, t-adv_on);
+   gpmc_set_one_timing(cs, GPMC_CS_CONFIG3, 8, 12, t-adv_rd_off);
+   gpmc_set_one_timing(cs, GPMC_CS_CONFIG3, 16, 20, t-adv_wr_off);
+
+   gpmc_set_one_timing(cs, GPMC_CS_CONFIG4, 0, 3, t-oe_on);
+   gpmc_set_one_timing(cs, GPMC_CS_CONFIG4, 8, 12, t-oe_off);
+   gpmc_set_one_timing(cs, GPMC_CS_CONFIG4, 16, 19, t-we_on);
+   gpmc_set_one_timing(cs, GPMC_CS_CONFIG4, 24, 28, t-we_off);
+
+   gpmc_set_one_timing(cs, GPMC_CS_CONFIG5, 24, 27, t-page_burst_access);
+   gpmc_set_one_timing(cs, GPMC_CS_CONFIG6, 0, 3, t-bus_turnaround);
+   gpmc_set_one_timing(cs, GPMC_CS_CONFIG6, 8, 11, t-cycle2cycle_delay);
+
+   if (gpmc_capability  GPMC_HAS_WR_ACCESS)
+   gpmc_set_one_timing(cs, GPMC_CS_CONFIG6, 24, 28, t-wr_access);
+   if (gpmc_capability  GPMC_HAS_WR_DATA_MUX_BUS)
+   gpmc_set_one_timing(cs, GPMC_CS_CONFIG6, 16, 19,
+   t-wr_data_mux_bus);
+
+   gpmc_cs_bool_timings(cs, t-bool_timings);
+}
+
 static __devinit int gpmc_setup_cs_irq(struct gpmc_cs_data *cs,
struct resource *res)
 {
-- 
1.7.10.2

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


[PATCH v6 08/13] ARM: OMAP2+: gpmc: holler if no configuration

2012-06-22 Thread Afzal Mohammed
Some of the GPMC peripherals depend on bootloader to do the
configuration. This facility is deprecated, notify user
about the present GPMC settings  inform that that relying
on bootloader for GPMC setting is deprecated.

Note: This has to be reverted once Kernel is updated with
sufficient details so that all the gpmc periherals can be
configured in Kernel for all boards instead of relying on
bootloader.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |  104 
 1 file changed, 104 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 1998285..9e3960e 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1056,6 +1056,110 @@ static void gpmc_cs_set_register_timings(int cs, const 
struct gpmc_timings *t)
gpmc_cs_bool_timings(cs, t-bool_timings);
 }
 
+static void gpmc_print_cs_config(int cs)
+{
+   u32 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+   dev_warn(gpmc_dev, GPMC CS%d depends on bootloader for config\n, cs);
+   dev_warn(gpmc_dev, Please update it in Kernel ASAP to prevent losing 
support for this peripheral\n);
+   dev_warn(gpmc_dev, Bootloader dependency for GPMC configuration is 
deprecated\n);
+
+   dev_warn(gpmc_dev, muxadddata: %s\n,
+   l  GPMC_CONFIG1_MUXADDDATA ? yes : no);
+   dev_warn(gpmc_dev, writetypesync: %s\n,
+   l  GPMC_CONFIG1_WRITETYPE_SYNC ? yes : no);
+   dev_warn(gpmc_dev, writemultiple: %s\n,
+   l  GPMC_CONFIG1_WRITEMULTIPLE_SUPP ? yes : no);
+   dev_warn(gpmc_dev, readtypesync: %s\n,
+   l  GPMC_CONFIG1_READTYPE_SYNC ? yes : no);
+   dev_warn(gpmc_dev, readmultiple: %s\n,
+   l  GPMC_CONFIG1_READMULTIPLE_SUPP ? yes : no);
+   dev_warn(gpmc_dev, wrapburst: %s\n,
+   l  GPMC_CONFIG1_WRAPBURST_SUPP ? yes : no);
+   dev_warn(gpmc_dev, devicetype: %s\n,
+   l  GPMC_CONFIG1_DEVICETYPE_NAND ? nand : nor);
+   dev_warn(gpmc_dev, devicesize: %d\n,
+   l  GPMC_CONFIG1_DEVICESIZE_16 ? 16 : 8);
+   dev_warn(gpmc_dev, pagelength: %d\n,
+   l  GPMC_CONFIG1_PAGE_LEN(~0) ?
+   (l  GPMC_CONFIG1_PAGE_LEN_16 ? 16 : 8) : 4);
+}
+static inline unsigned gpmc_get_one_timing(int cs, int reg, int start, int end)
+{
+   u32 l = gpmc_cs_read_reg(cs, reg);
+   unsigned mask;
+
+   mask = (1  (end - start + 1)) - 1;
+   l = (mask  start);
+   return l = start;
+}
+
+static void gpmc_print_cs_timings(int cs)
+{
+   dev_warn(gpmc_dev, GPMC CS%d depends on bootloader for timing\n, cs);
+   dev_warn(gpmc_dev, Please update it in Kernel ASAP to prevent losing 
support for this peripheral\n);
+   dev_warn(gpmc_dev, Bootloader dependency for GPMC configuration is 
deprecated\n);
+
+   dev_warn(gpmc_dev, fclk period: %lups\n, gpmc_get_fclk_period());
+   dev_warn(gpmc_dev, sync_clk: %u\n,
+   gpmc_get_one_timing(cs, GPMC_CS_CONFIG1, 0, 1));
+   dev_warn(gpmc_dev, wait_monitoring: %u\n,
+   gpmc_get_one_timing(cs, GPMC_CS_CONFIG1, 18, 19));
+   dev_warn(gpmc_dev, clk_activation: %u\n,
+   gpmc_get_one_timing(cs, GPMC_CS_CONFIG1, 25, 26));
+   dev_warn(gpmc_dev, cs_on: %u\n,
+   gpmc_get_one_timing(cs, GPMC_CS_CONFIG2, 0, 3));
+   dev_warn(gpmc_dev, cs_rd_off: %u\n,
+   gpmc_get_one_timing(cs, GPMC_CS_CONFIG2, 8, 12));
+   dev_warn(gpmc_dev, cs_wr_off: %u\n,
+   gpmc_get_one_timing(cs, GPMC_CS_CONFIG2, 16, 20));
+   dev_warn(gpmc_dev, adv_on: %u\n,
+   gpmc_get_one_timing(cs, GPMC_CS_CONFIG3, 0, 3));
+   dev_warn(gpmc_dev, adv_rd_off: %u\n,
+   gpmc_get_one_timing(cs, GPMC_CS_CONFIG3, 8, 12));
+   dev_warn(gpmc_dev, adv_wr_off: %u\n,
+   gpmc_get_one_timing(cs, GPMC_CS_CONFIG3, 16, 20));
+   dev_warn(gpmc_dev, oe_on: %u\n,
+   gpmc_get_one_timing(cs, GPMC_CS_CONFIG4, 0, 3));
+   dev_warn(gpmc_dev, oe_off: %u\n,
+   gpmc_get_one_timing(cs, GPMC_CS_CONFIG4, 8, 12));
+   dev_warn(gpmc_dev, we_on: %u\n,
+   gpmc_get_one_timing(cs, GPMC_CS_CONFIG4, 16, 19));
+   dev_warn(gpmc_dev, we_off: %u\n,
+   gpmc_get_one_timing(cs, GPMC_CS_CONFIG4, 24, 28));
+   dev_warn(gpmc_dev, rd_cycle: %u\n,
+   gpmc_get_one_timing(cs, GPMC_CS_CONFIG5, 0, 4));
+   dev_warn(gpmc_dev, wr_cycle: %u\n,
+   gpmc_get_one_timing(cs, GPMC_CS_CONFIG5, 8, 12));
+   dev_warn(gpmc_dev, acess: %u\n,
+   gpmc_get_one_timing(cs, GPMC_CS_CONFIG5, 16, 20));
+   dev_warn(gpmc_dev, page_burst_access: %u\n,
+   gpmc_get_one_timing(cs

[PATCH v6 09/13] ARM: OMAP2+: gpmc: waitpin helper

2012-06-22 Thread Afzal Mohammed
Helper for configuring waitpin. There are two parts to it;
configuring at CS level and the other at device level.
A device embedding multiple CS has been provided the
capability to use same waitpin (different waitpins has not
been supported as presently there are no GPMC peripherals
doing so)

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |  123 
 arch/arm/plat-omap/include/plat/gpmc.h |9 +++
 2 files changed, 132 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 9e3960e..15688da 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -75,6 +75,8 @@
 #defineGPMC_CONFIG6_CYCLE2CYCLEDIFFCSENBIT(6)
 #defineGPMC_CONFIG6_CYCLE2CYCLESAMECSENBIT(7)
 
+#defineGPMC_CONFIG_WAITPIN_POLARITY_SHIFT  0x8
+
 #define GPMC_CS0_OFFSET0x60
 #define GPMC_CS_SIZE   0x30
 
@@ -99,6 +101,14 @@
  */
 #defineGPMC_NR_IRQ 2
 
+enum {
+   GPMC_WAITPIN_IDX0,
+   GPMC_WAITPIN_IDX1,
+   GPMC_WAITPIN_IDX2,
+   GPMC_WAITPIN_IDX3,
+   GPMC_MAX_NR_WAITPIN
+};
+
 struct gpmc_client_irq {
unsignedirq;
u32 bitmask;
@@ -146,6 +156,9 @@ struct gpmc_peripheral {
struct platform_device  *pdev;
 };
 
+static unsigned gpmc_waitpin_map;
+static unsigned gpmc_waitpin_nr = GPMC_MAX_NR_WAITPIN;
+
 static struct gpmc_client_irq gpmc_client_irq[GPMC_NR_IRQ];
 static struct irq_chip gpmc_irq_chip;
 static unsigned gpmc_irq_start;
@@ -1160,6 +1173,62 @@ static void gpmc_print_cs_timings(int cs)
gpmc_get_one_timing(cs, GPMC_CS_CONFIG6, 7, 7));
 }
 
+static int gpmc_setup_cs_waitpin(struct gpmc_peripheral *g_per, unsigned cs,
+   unsigned conf)
+{
+   unsigned idx;
+   bool polarity = 0;
+   u32 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+   switch (conf  GPMC_WAITPIN_MASK) {
+   case GPMC_WAITPIN_0:
+   idx =  GPMC_WAITPIN_IDX0;
+   break;
+   case GPMC_WAITPIN_1:
+   idx =  GPMC_WAITPIN_IDX1;
+   break;
+   case GPMC_WAITPIN_2:
+   idx =  GPMC_WAITPIN_IDX2;
+   break;
+   case GPMC_WAITPIN_3:
+   idx =  GPMC_WAITPIN_IDX3;
+   break;
+   /* no waitpin */
+   case 0:
+   return 0;
+   break;
+   default:
+   dev_err(gpmc_dev, multiple waitpins selected on CS:%u\n, cs);
+   return -EINVAL;
+   break;
+   }
+
+   polarity = !!(conf  GPMC_WAITPIN_ACTIVE_HIGH);
+
+   if (g_per-have_waitpin) {
+   if (g_per-waitpin != idx ||
+   g_per-waitpin_high != polarity) {
+   dev_err(gpmc_dev, error: conflict: waitpin %u with 
polarity %d on device %s.%d\n,
+   g_per-waitpin, g_per-waitpin_high,
+   g_per-name, g_per-id);
+   return -EBUSY;
+   }
+   } else {
+   g_per-have_waitpin = true;
+   g_per-waitpin = idx;
+   g_per-waitpin_high = polarity;
+   }
+
+   l |= conf  GPMC_CONFIG1_WAIT_WRITE_MON;
+   l |= conf  GPMC_CONFIG1_WAIT_READ_MON;
+   l = ~GPMC_CONFIG1_WAIT_PIN_SEL_MASK;
+   l |= GPMC_CONFIG1_WAIT_PIN_SEL(idx);
+
+   gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l);
+
+   return 0;
+}
+
 static __devinit int gpmc_setup_cs_irq(struct gpmc_cs_data *cs,
struct resource *res)
 {
@@ -1183,6 +1252,55 @@ static __devinit int gpmc_setup_cs_irq(struct 
gpmc_cs_data *cs,
return n;
 }
 
+static inline int gpmc_waitpin_is_reserved(unsigned waitpin)
+{
+   return gpmc_waitpin_map  (0x1  waitpin);
+}
+
+static inline void gpmc_reserve_waitpin(unsigned waitpin)
+{
+   gpmc_waitpin_map = ~(0x1  waitpin);
+   gpmc_waitpin_map |= (0x1  waitpin);
+}
+
+static int gpmc_waitpin_request(unsigned waitpin)
+{
+   if (!(waitpin  gpmc_waitpin_nr))
+   return -ENODEV;
+
+   if (gpmc_waitpin_is_reserved(waitpin))
+   return -EBUSY;
+   else
+   gpmc_reserve_waitpin(waitpin);
+
+   return 0;
+}
+
+static int gpmc_setup_waitpin(struct gpmc_peripheral *g_per)
+{
+   int ret;
+   u32 l, shift;
+
+   if (!g_per-have_waitpin)
+   return 0;
+
+   ret = gpmc_waitpin_request(g_per-waitpin);
+   if (IS_ERR_VALUE(ret)) {
+   dev_err(gpmc_dev, waitpin %u reserved\n, g_per-waitpin);
+   return ret;
+   }
+
+   l = gpmc_read_reg(GPMC_CONFIG);
+   shift = g_per-waitpin + GPMC_CONFIG_WAITPIN_POLARITY_SHIFT;
+   if (g_per-waitpin_high)
+   l |= 1  shift;
+   else
+   l = ~(1  shift

[PATCH v6 10/13] ARM: OMAP2+: gpmc: handle connected peripherals

2012-06-22 Thread Afzal Mohammed
Platform will provide driver with configuration details for
each CS like configuration, timing, interrupts. Setup GPMC
based on it. Platform data also provides platform data 
resources used for connected peripheral (eg. gpio irq).
GPMC driver tunnels those information to respective driver.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |  142 
 1 file changed, 142 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 15688da..ac66267 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -156,6 +156,8 @@ struct gpmc_peripheral {
struct platform_device  *pdev;
 };
 
+static struct gpmc_peripheral gpmc_peripheral[GPMC_CS_NUM];
+static unsigned gpmc_num_peripheral;
 static unsigned gpmc_waitpin_map;
 static unsigned gpmc_waitpin_nr = GPMC_MAX_NR_WAITPIN;
 
@@ -1229,6 +1231,37 @@ static int gpmc_setup_cs_waitpin(struct gpmc_peripheral 
*g_per, unsigned cs,
return 0;
 }
 
+static int gpmc_setup_cs_config_timing(struct gpmc_peripheral *g_per,
+   struct gpmc_cs_data *cs)
+{
+   int ret;
+
+   /* some boards rely on bootloader for configuration */
+   if (cs-have_config) {
+   gpmc_setup_cs_config(cs-cs, cs-config);
+   ret = gpmc_setup_cs_waitpin(g_per, cs-cs, cs-config);
+   if (IS_ERR_VALUE(ret)) {
+   dev_err(gpmc_dev, error: waitpin on CS %d\n, cs-cs);
+   return ret;
+   }
+   } else
+   gpmc_print_cs_config(cs-cs);
+
+   /* some boards rely on bootloader for timing */
+   if (cs-time_ctrl.type == has_period) {
+   ret = gpmc_cs_set_timings(cs-cs, cs-time_ctrl.timings);
+   if (IS_ERR_VALUE(ret)) {
+   dev_err(gpmc_dev, error: timing on CS: %d\n, cs-cs);
+   return ret;
+   }
+   } else if (cs-time_ctrl.type == has_clock)
+   gpmc_cs_set_register_timings(cs-cs, cs-time_ctrl.timings);
+   else
+   gpmc_print_cs_timings(cs-cs);
+
+   return 0;
+}
+
 static __devinit int gpmc_setup_cs_irq(struct gpmc_cs_data *cs,
struct resource *res)
 {
@@ -1301,11 +1334,99 @@ static int gpmc_setup_waitpin(struct gpmc_peripheral 
*g_per)
return 0;
 }
 
+static __devinit int gpmc_setup_cs(struct gpmc_peripheral *g_per,
+   struct gpmc_cs_data *cs, struct resource *res)
+{
+   int num, ret;
+
+   ret = gpmc_setup_cs_mem(cs, res);
+   if (IS_ERR_VALUE(ret))
+   return ret;
+
+   ret = gpmc_setup_cs_config_timing(g_per, cs);
+   if (IS_ERR_VALUE(ret))
+   return ret;
+
+   num = gpmc_setup_cs_irq(cs, res + 1); /* +1 to account for memory */
+
+   return num + 1; /* +1 to account for memory*/
+}
+
+static __devinit int gpmc_setup_device(struct gpmc_peripheral *g_per,
+   struct gpmc_device_pdata *gdp)
+{
+   int i, n, ret;
+   struct gpmc_cs_data *cs;
+
+   for (i = 0, n = gdp-num_cs, cs = gdp-cs_data;
+   i  gdp-num_cs; i++, cs++)
+   n += hweight32(cs-irq_config);
+
+   g_per-gpmc_res = devm_kzalloc(gpmc_dev, sizeof(*g_per-gpmc_res) * n,
+   GFP_KERNEL);
+   if (g_per-gpmc_res == NULL) {
+   dev_err(gpmc_dev, error: memory allocation\n);
+   return -ENOMEM;
+   }
+
+   for (i = 0, cs = gdp-cs_data, g_per-gpmc_res_cnt = 0;
+   i  gdp-num_cs; cs++, i++) {
+   ret = gpmc_setup_cs(g_per, cs,
+   g_per-gpmc_res + g_per-gpmc_res_cnt);
+   if (IS_ERR_VALUE(ret) ||
+   IS_ERR_VALUE(gpmc_setup_waitpin(g_per))) {
+   dev_err(gpmc_dev, error: setup for %s\n, gdp-name);
+   devm_kfree(gpmc_dev, g_per-gpmc_res);
+   g_per-gpmc_res = NULL;
+   g_per-gpmc_res_cnt = 0;
+   return -EINVAL;
+   } else
+   g_per-gpmc_res_cnt += ret;
+   }
+
+   g_per-name = gdp-name;
+   g_per-id = gdp-id;
+   g_per-pdata = gdp-pdata;
+   g_per-pdata_size = gdp-pdata_size;
+   g_per-per_res = gdp-per_res;
+   g_per-per_res_cnt = gdp-per_res_cnt;
+
+   return 0;
+}
+
+static __devinit
+struct platform_device *gpmc_create_device(struct gpmc_peripheral *p)
+{
+   int num = p-per_res_cnt + p-gpmc_res_cnt;
+   struct resource *res;
+
+   res = devm_kzalloc(gpmc_dev, sizeof(struct resource) * num,
+   GFP_KERNEL);
+   if (!res) {
+   dev_err(gpmc_dev, error: allocating memory\n

[PATCH v6 11/13] ARM: OMAP2+: gpmc: cs reconfigure helper

2012-06-22 Thread Afzal Mohammed
Helper for reconfiguring CS. This helps if a
peripheral needs to reconfigure GPMC settings
different from the one which was configured
during probe.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |   32 
 arch/arm/plat-omap/include/plat/gpmc.h |2 ++
 2 files changed, 34 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index ac66267..3729136 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1420,6 +1420,38 @@ struct platform_device *gpmc_create_device(struct 
gpmc_peripheral *p)
return p-pdev;
 }
 
+static int gpmc_match_device(char *name, int id)
+{
+   int i;
+   struct gpmc_peripheral *g_per = gpmc_peripheral;
+
+   for (i = 0; i  gpmc_num_peripheral; i++, g_per++)
+   if (!strcmp(g_per-name, name)  g_per-id == id)
+   return i;
+
+   return -ENOENT;
+}
+
+int gpmc_cs_reconfigure(char *name, int id, struct gpmc_cs_data *c)
+{
+   int i;
+
+   i = gpmc_match_device(name, id);
+   if (IS_ERR_VALUE(i)) {
+   dev_err(gpmc_dev, no device %s.%d to configure\n, name, id);
+   return i;
+   }
+
+   if (IS_ERR_VALUE(gpmc_setup_cs_config_timing(gpmc_peripheral + i, c))) {
+   dev_err(gpmc_dev, error: configure device %s.%d\n, name, id);
+   return i;
+   }
+
+   return gpmc_setup_waitpin(gpmc_peripheral + i);
+
+}
+EXPORT_SYMBOL_GPL(gpmc_cs_reconfigure);
+
 static __devinit int gpmc_probe(struct platform_device *pdev)
 {
u32 l;
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h 
b/arch/arm/plat-omap/include/plat/gpmc.h
index 1185490..7909867 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -248,6 +248,8 @@ extern int gpmc_cs_configure(int cs, int cmd, int wval);
 extern int gpmc_nand_read(int cs, int cmd);
 extern int gpmc_nand_write(int cs, int cmd, int wval);
 
+extern int gpmc_cs_reconfigure(char *name, int id, struct gpmc_cs_data *c);
+
 int gpmc_enable_hwecc(int cs, int mode, int dev_width, int ecc_size);
 int gpmc_calculate_ecc(int cs, const u_char *dat, u_char *ecc_code);
 
-- 
1.7.10.2

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


[PATCH v6 12/13] ARM: OMAP2+: gpmc: update nand register info

2012-06-22 Thread Afzal Mohammed
GPMC has dedicated NAND handling blocks and have a few
registers exclusively meant for NAND operations. These
registers can be handled by OMAP NAND driver as it is
meant for handling NAND on GPMC. Update OMAP NAND
platform data with GPMC-NAND register details so that
OMAP NAND driver can handle by itself instead of
relying on GPMC exported symbols.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |9 -
 arch/arm/plat-omap/include/plat/gpmc.h |1 +
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 3729136..c8e967f 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -28,6 +28,7 @@
 
 #include asm/mach-types.h
 #include plat/gpmc.h
+#include plat/nand.h
 #include plat/omap_device.h
 
 #include plat/sdrc.h
@@ -1497,12 +1498,18 @@ static __devinit int gpmc_probe(struct platform_device 
*pdev)
gpmc_waitpin_nr = gp-waitpin_nr;
 
/* Traverse NULL terminated array of peripheral pointers and setup */
-   for (gdq = gp-device_pdata, g_per = gpmc_peripheral; *gdq; gdq++)
+   for (gdq = gp-device_pdata, g_per = gpmc_peripheral; *gdq; gdq++) {
+   if ((*gdq)-is_nand) {
+   struct omap_nand_platform_data *p = (*gdq)-pdata;
+
+   gpmc_update_nand_reg(p-reg, p-cs);
+   }
if (IS_ERR_VALUE(gpmc_setup_device(g_per, *gdq)))
dev_err(gpmc_dev, gpmc setup on %s failed\n,
(*gdq)-name);
else
g_per++;
+   }
gpmc_num_peripheral = g_per - gpmc_peripheral;
 
for (l = 0, g_per = gpmc_peripheral;
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h 
b/arch/arm/plat-omap/include/plat/gpmc.h
index 7909867..0085a01 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -196,6 +196,7 @@ struct gpmc_device_pdata {
unsignedper_res_cnt;
struct gpmc_cs_data *cs_data;
unsignednum_cs;
+   boolis_nand;
 };
 
 struct gpmc_pdata {
-- 
1.7.10.2

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


[PATCH v6 13/13] ARM: OMAP2+: gpmc: configure writeprotect

2012-06-22 Thread Afzal Mohammed
GPMC has a writeprotect pin that can be connected to
peripherals. Default is to disable writeprotect. In
case of conflicting requirement of writeprotect, it
will be left in enabled state to be on safer side,
along with a warning to attract user attention.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |   42 
 arch/arm/plat-omap/include/plat/gpmc.h |2 ++
 2 files changed, 44 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index c8e967f..1b0b526 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -110,6 +110,12 @@ enum {
GPMC_MAX_NR_WAITPIN
 };
 
+enum {
+   NONE,
+   OFF,
+   ON
+};
+
 struct gpmc_client_irq {
unsignedirq;
u32 bitmask;
@@ -161,6 +167,7 @@ static struct gpmc_peripheral gpmc_peripheral[GPMC_CS_NUM];
 static unsigned gpmc_num_peripheral;
 static unsigned gpmc_waitpin_map;
 static unsigned gpmc_waitpin_nr = GPMC_MAX_NR_WAITPIN;
+static unsigned gpmc_writeprotect;
 
 static struct gpmc_client_irq gpmc_client_irq[GPMC_NR_IRQ];
 static struct irq_chip gpmc_irq_chip;
@@ -192,6 +199,18 @@ static u32 gpmc_read_reg(int idx)
return __raw_readl(gpmc_base + idx);
 }
 
+static inline void gpmc_modify_reg(int idx, u32 mask, bool value)
+{
+   u32 l;
+
+   l = gpmc_read_reg(idx);
+   if (value)
+   l |= mask;
+   else
+   l = ~mask;
+   gpmc_write_reg(idx, l);
+}
+
 static void gpmc_cs_write_byte(int cs, int idx, u8 val)
 {
void __iomem *reg_addr;
@@ -991,6 +1010,7 @@ static __devinit int gpmc_setup_cs_mem(struct gpmc_cs_data 
*cs,
 static void gpmc_setup_cs_config(unsigned cs, unsigned conf)
 {
u32 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+   unsigned wp;
 
l = ~(GPMC_CONFIG1_MUXADDDATA |
GPMC_CONFIG1_WRITETYPE_SYNC |
@@ -1025,6 +1045,19 @@ static void gpmc_setup_cs_config(unsigned cs, unsigned 
conf)
l |= conf;
 
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l);
+
+   if (conf  GPMC_CONFIG_ENABLE_WRITEPROTECT)
+   wp = ON;
+   else
+   wp = OFF;
+
+   if (gpmc_writeprotect) {
+   if (gpmc_writeprotect != wp) {
+   dev_warn(gpmc_dev, conflicting writeprotect requests, 
writeprotect is left enabled\n);
+   gpmc_writeprotect = ON;
+   }
+   } else
+   gpmc_writeprotect = wp;
 }
 
 static inline void gpmc_set_one_timing(int cs, int reg, int start,
@@ -1453,6 +1486,12 @@ int gpmc_cs_reconfigure(char *name, int id, struct 
gpmc_cs_data *c)
 }
 EXPORT_SYMBOL_GPL(gpmc_cs_reconfigure);
 
+static inline void gpmc_setup_writeprotect(void)
+{
+   gpmc_modify_reg(GPMC_CONFIG, GPMC_CONFIG_WRITEPROTECT,
+   gpmc_writeprotect == ON ? false : true);
+}
+
 static __devinit int gpmc_probe(struct platform_device *pdev)
 {
u32 l;
@@ -1512,6 +1551,8 @@ static __devinit int gpmc_probe(struct platform_device 
*pdev)
}
gpmc_num_peripheral = g_per - gpmc_peripheral;
 
+   gpmc_setup_writeprotect();
+
for (l = 0, g_per = gpmc_peripheral;
l  gpmc_num_peripheral; l++, g_per++)
if (IS_ERR(gpmc_create_device(g_per)))
@@ -1528,6 +1569,7 @@ static __exit int gpmc_remove(struct platform_device 
*pdev)
for (; gpmc_num_peripheral; g_per++, gpmc_num_peripheral--)
platform_device_unregister(g_per-pdev);
 
+   gpmc_writeprotect = NONE;
gpmc_waitpin_map = 0;
gpmc_waitpin_nr = GPMC_MAX_NR_WAITPIN;
gpmc_free_irq();
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h 
b/arch/arm/plat-omap/include/plat/gpmc.h
index 0085a01..3de05dc 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -79,6 +79,8 @@
 #define GPMC_CONFIG1_FCLK_DIV4  (GPMC_CONFIG1_FCLK_DIV(3))
 #define GPMC_CONFIG7_CSVALID   (1  6)
 
+#defineGPMC_CONFIG_ENABLE_WRITEPROTECT (1  5)
+
 #defineGPMC_WAITPIN_ACTIVE_HIGH(1  4)
 #defineGPMC_WAITPIN_ACTIVE_LOW (0  4)
 #defineGPMC_WAITPIN_0  (1  0)
-- 
1.7.10.2

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


[PATCH v5 0/3] Prepare for GPMC driver conversion

2012-06-27 Thread Afzal Mohammed

Hi,

Objective of this series is to make things easy for GPMC driver
conversion series by separating out more things from driver
conversion series.

This series,
1. Unifies NAND platform initialization functions
2. Prepares OneNAND platform code for gpmc driver migration
3. Handles additional timings in Kernel

This series is based on 3.5-rc1  made on top of
[PATCH v2 00/10] Prepare for GPMC driver conversion (w.r.t MTD)
{http://www.mail-archive.com/linux-omap@vger.kernel.org/msg70096.html}

These changes has been tested with omap3evm  beagle board. Relevant
GPMC peripherals that got tested by this were NAND (beagle) and
OneNAND (using local patches for omap3evm)

Regards
Afzal

v5:
1. Use flags for sync_read/write, hv, vhf
v4:
1. Reorganize OneNAND set_sync/async functions in a better way
v3:
1. Refactor OneNAND set_sync/async functions to separate out timing
 and configurations
2. Handle bool type timings too
3. Swap patches 2  3 due to dependency of OneNAND change on  newly
 added bool type timings
v2:
1. Make use of timing api for setting clock activation time, and
 remove direct writing to register for clock activation. Peripherals
 making use of it were tusb6010  onenand
2. Move ensuring that async mode in OneNAND has been setup from
 set_sync to setup function, improve commit message


Afzal Mohammed (3):
  ARM: OMAP2+: nand: unify init functions
  ARM: OMAP2+: gpmc: handle additional timings
  ARM: OMAP2+: onenand: prepare for gpmc driver migration

 arch/arm/mach-omap2/board-devkit8000.c |8 +-
 arch/arm/mach-omap2/board-flash.c  |   45 ---
 arch/arm/mach-omap2/board-flash.h  |6 +-
 arch/arm/mach-omap2/board-igep0020.c   |2 +-
 arch/arm/mach-omap2/board-ldp.c|4 +-
 arch/arm/mach-omap2/board-omap3beagle.c|8 +-
 arch/arm/mach-omap2/board-omap3touchbook.c |8 +-
 arch/arm/mach-omap2/board-overo.c  |7 +-
 arch/arm/mach-omap2/board-zoom.c   |5 +-
 arch/arm/mach-omap2/common-board-devices.c |   46 ---
 arch/arm/mach-omap2/common-board-devices.h |1 -
 arch/arm/mach-omap2/gpmc-onenand.c |  200 
 arch/arm/mach-omap2/gpmc.c |   45 +++
 arch/arm/mach-omap2/usb-tusb6010.c |3 +-
 arch/arm/plat-omap/include/plat/gpmc.h |   19 +++
 15 files changed, 235 insertions(+), 172 deletions(-)

-- 
1.7.10.2

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


[PATCH v5 1/3] ARM: OMAP2+: nand: unify init functions

2012-06-27 Thread Afzal Mohammed
Helper function for updating nand platform data has been
added the capability to take timing structure arguement.
Usage of omap_nand_flash_init() has been replaced by modifed
one, omap_nand_flash_init was doing things similar to
board_nand_init except that NAND CS# were being acquired
based on bootloader setting. As CS# is hardwired for a given
board, acquiring gpmc CS# has been removed, and updated with
the value on board.

NAND CS# used in beagle board was found to be CS0.
Thomas Weber thomas.weber.li...@googlemail.com reported
that value of devkit8000 to be CS0. Overo board was found
to be using CS0 based on u-boot, while google grep says
omap3touchbook too has CS0.

Signed-off-by: Afzal Mohammed af...@ti.com
Reviewed-by: Jon Hunter jon-hun...@ti.com
---
 arch/arm/mach-omap2/board-devkit8000.c |8 +++--
 arch/arm/mach-omap2/board-flash.c  |   45 ++-
 arch/arm/mach-omap2/board-flash.h  |6 ++--
 arch/arm/mach-omap2/board-igep0020.c   |2 +-
 arch/arm/mach-omap2/board-ldp.c|4 +--
 arch/arm/mach-omap2/board-omap3beagle.c|8 +++--
 arch/arm/mach-omap2/board-omap3touchbook.c |8 +++--
 arch/arm/mach-omap2/board-overo.c  |7 +++--
 arch/arm/mach-omap2/board-zoom.c   |5 +--
 arch/arm/mach-omap2/common-board-devices.c |   46 
 arch/arm/mach-omap2/common-board-devices.h |1 -
 11 files changed, 56 insertions(+), 84 deletions(-)

diff --git a/arch/arm/mach-omap2/board-devkit8000.c 
b/arch/arm/mach-omap2/board-devkit8000.c
index 6567c1c..6ee429a 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -59,8 +59,11 @@
 
 #include mux.h
 #include hsmmc.h
+#include board-flash.h
 #include common-board-devices.h
 
+#defineNAND_CS 0
+
 #define OMAP_DM9000_GPIO_IRQ   25
 #define OMAP3_DEVKIT_TS_GPIO   27
 
@@ -628,8 +631,9 @@ static void __init devkit8000_init(void)
 
usb_musb_init(NULL);
usbhs_init(usbhs_bdata);
-   omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions,
-ARRAY_SIZE(devkit8000_nand_partitions));
+   board_nand_init(devkit8000_nand_partitions,
+   ARRAY_SIZE(devkit8000_nand_partitions), NAND_CS,
+   NAND_BUSWIDTH_16, NULL);
 
/* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal(sdrc_cke0, OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-flash.c 
b/arch/arm/mach-omap2/board-flash.c
index 70a81f9..0ee820b 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -108,41 +108,41 @@ __init board_onenand_init(struct mtd_partition 
*nor_parts, u8 nr_parts, u8 cs)
defined(CONFIG_MTD_NAND_OMAP2_MODULE)
 
 /* Note that all values in this struct are in nanoseconds */
-static struct gpmc_timings nand_timings = {
+struct gpmc_timings nand_default_timings[1] = {
+   {
+   .sync_clk = 0,
 
-   .sync_clk = 0,
+   .cs_on = 0,
+   .cs_rd_off = 36,
+   .cs_wr_off = 36,
 
-   .cs_on = 0,
-   .cs_rd_off = 36,
-   .cs_wr_off = 36,
+   .adv_on = 6,
+   .adv_rd_off = 24,
+   .adv_wr_off = 36,
 
-   .adv_on = 6,
-   .adv_rd_off = 24,
-   .adv_wr_off = 36,
+   .we_off = 30,
+   .oe_off = 48,
 
-   .we_off = 30,
-   .oe_off = 48,
+   .access = 54,
+   .rd_cycle = 72,
+   .wr_cycle = 72,
 
-   .access = 54,
-   .rd_cycle = 72,
-   .wr_cycle = 72,
-
-   .wr_access = 30,
-   .wr_data_mux_bus = 0,
+   .wr_access = 30,
+   .wr_data_mux_bus = 0,
+   },
 };
 
-static struct omap_nand_platform_data board_nand_data = {
-   .gpmc_t = nand_timings,
-};
+static struct omap_nand_platform_data board_nand_data;
 
 void
-__init board_nand_init(struct mtd_partition *nand_parts,
-   u8 nr_parts, u8 cs, int nand_type)
+__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
+   int nand_type, struct gpmc_timings *gpmc_t)
 {
board_nand_data.cs  = cs;
board_nand_data.parts   = nand_parts;
board_nand_data.nr_parts= nr_parts;
board_nand_data.devsize = nand_type;
+   board_nand_data.gpmc_t  = gpmc_t;
 
board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs;
@@ -243,5 +243,6 @@ void __init board_flash_init(struct flash_partitions 
partition_info[],
pr_err(NAND: Unable to find configuration in GPMC\n);
else
board_nand_init(partition_info[2].parts,
-   partition_info[2].nr_parts, nandcs, nand_type);
+   partition_info[2].nr_parts, nandcs

[PATCH v5 2/3] ARM: OMAP2+: gpmc: handle additional timings

2012-06-27 Thread Afzal Mohammed
Configure busturnaround, cycle2cycledelay, waitmonitoringtime,
clkactivationtime in gpmc_cs_set_timings(). This is done so
that boards can configure these parameters of gpmc in Kernel
instead of relying on bootloader. Also configure bool type
timings like extradelay.

This needed change to two existing users that were configuring
clk activation time by directly writing to registers. Thanks to
Tony for making me aware of the issue  being kind enough to
test this change.

Signed-off-by: Afzal Mohammed af...@ti.com
---

v3:
Handle bool type timings too
v2:
Make use of timing api for setting clock activation time, and
 remove direct writing to register for clock activation. Peripherals
 making use of it were tusb6010  onenand

 arch/arm/mach-omap2/gpmc-onenand.c |3 ++-
 arch/arm/mach-omap2/gpmc.c |   45 
 arch/arm/mach-omap2/usb-tusb6010.c |3 ++-
 arch/arm/plat-omap/include/plat/gpmc.h |   19 ++
 4 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c 
b/arch/arm/mach-omap2/gpmc-onenand.c
index 71d7c07..8863e0a 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -329,6 +329,8 @@ static int omap2_onenand_set_sync_mode(struct 
omap_onenand_platform_data *cfg,
t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div +
 ticks_cez);
 
+   t.clk_activation = fclk_offset_ns;
+
/* Write */
if (sync_write) {
t.adv_wr_off = t.adv_rd_off;
@@ -362,7 +364,6 @@ static int omap2_onenand_set_sync_mode(struct 
omap_onenand_platform_data *cfg,
  (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) |
  (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) |
  (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) |
- GPMC_CONFIG1_CLKACTIVATIONTIME(fclk_offset) |
  GPMC_CONFIG1_PAGE_LEN(2) |
  (cpu_is_omap34xx() ? 0 :
(GPMC_CONFIG1_WAIT_READ_MON |
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 578fd4c..8b0978f 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -64,6 +64,13 @@
 #define GPMC_ECC_CTRL_ECCREG8  0x008
 #define GPMC_ECC_CTRL_ECCREG9  0x009
 
+#defineGPMC_CONFIG2_CSEXTRADELAY   BIT(7)
+#defineGPMC_CONFIG3_ADVEXTRADELAY  BIT(7)
+#defineGPMC_CONFIG4_OEEXTRADELAY   BIT(7)
+#defineGPMC_CONFIG4_WEEXTRADELAY   BIT(23)
+#defineGPMC_CONFIG6_CYCLE2CYCLEDIFFCSENBIT(6)
+#defineGPMC_CONFIG6_CYCLE2CYCLESAMECSENBIT(7)
+
 #define GPMC_CS0_OFFSET0x60
 #define GPMC_CS_SIZE   0x30
 
@@ -220,6 +227,36 @@ unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
return ticks * gpmc_get_fclk_period() / 1000;
 }
 
+static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value)
+{
+   u32 l;
+
+   l = gpmc_cs_read_reg(cs, reg);
+   if (value)
+   l |= mask;
+   else
+   l = ~mask;
+   gpmc_cs_write_reg(cs, reg, l);
+}
+
+static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
+{
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG1,
+   GPMC_CONFIG1_TIME_PARA_GRAN, p-time_para_granularity);
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG2,
+   GPMC_CONFIG2_CSEXTRADELAY, p-cs_extra_delay);
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG3,
+   GPMC_CONFIG3_ADVEXTRADELAY, p-adv_extra_delay);
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+   GPMC_CONFIG4_OEEXTRADELAY, p-oe_extra_delay);
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+   GPMC_CONFIG4_OEEXTRADELAY, p-we_extra_delay);
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
+   GPMC_CONFIG6_CYCLE2CYCLESAMECSEN, p-cycle2cyclesamecsen);
+   gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
+   GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN, p-cycle2cyclediffcsen);
+}
+
 #ifdef DEBUG
 static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
   int time, const char *name)
@@ -313,6 +350,12 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings 
*t)
 
GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
 
+   GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround);
+   GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycle_delay);
+
+   GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring);
+   GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation);
+
if (cpu_is_omap34xx()) {
GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access);
@@ -332,6 +375,8 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings 
*t

[PATCH v5 3/3] ARM: OMAP2+: onenand: prepare for gpmc driver migration

2012-06-27 Thread Afzal Mohammed
Reorganize gpmc-onenand initialization so that changes
required for gpmc driver migration can be made smooth.

Ensuring sync read/write are disabled in onenand cannot
be expected to work properly unless GPMC is setup, this
has been removed.

Refactor set_async_mode  set_sync_mode functions to
separate out timing calculation  actual configuration
(GPMC  OneNAND side).

Thanks to Jon for his suggestions.

Signed-off-by: Afzal Mohammed af...@ti.com
Reviewed-by: Jon Hunter jon-hun...@ti.com
---

v5:
Use flags for sync_read/write, hv, vhf
v4:
Reorganize set_sync/async functions in a better way
v3:
Refactor set_sync/async functions to separate out timing and
 configurations
v2:
Move ensuring that async mode in OneNAND has been setup from
 set_sync to setup function, improve commit message

 arch/arm/mach-omap2/gpmc-onenand.c |  197 
 1 file changed, 111 insertions(+), 86 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c 
b/arch/arm/mach-omap2/gpmc-onenand.c
index 8863e0a..c8a9487 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -15,6 +15,7 @@
 #include linux/platform_device.h
 #include linux/mtd/onenand_regs.h
 #include linux/io.h
+#include linux/err.h
 
 #include asm/mach/flash.h
 
@@ -25,6 +26,14 @@
 
 #defineONENAND_IO_SIZE SZ_128K
 
+#defineONENAND_FLAG_SYNCREAD   (1  0)
+#defineONENAND_FLAG_SYNCWRITE  (1  1)
+#defineONENAND_FLAG_HF (1  2)
+#defineONENAND_FLAG_VHF(1  3)
+
+static unsigned onenand_flags;
+static unsigned latency;
+
 static struct omap_onenand_platform_data *gpmc_onenand_data;
 
 static struct resource gpmc_onenand_resource = {
@@ -38,11 +47,9 @@ static struct platform_device gpmc_onenand_device = {
.resource   = gpmc_onenand_resource,
 };
 
-static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base)
+static struct gpmc_timings omap2_onenand_calc_async_timings(void)
 {
struct gpmc_timings t;
-   u32 reg;
-   int err;
 
const int t_cer = 15;
const int t_avdp = 12;
@@ -55,11 +62,6 @@ static int omap2_onenand_set_async_mode(int cs, void __iomem 
*onenand_base)
const int t_wpl = 40;
const int t_wph = 30;
 
-   /* Ensure sync read and sync write are disabled */
-   reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
-   reg = ~ONENAND_SYS_CFG1_SYNC_READ  ~ONENAND_SYS_CFG1_SYNC_WRITE;
-   writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
-
memset(t, 0, sizeof(t));
t.sync_clk = 0;
t.cs_on = 0;
@@ -86,25 +88,30 @@ static int omap2_onenand_set_async_mode(int cs, void 
__iomem *onenand_base)
t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
t.wr_cycle  = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
 
+   return t;
+}
+
+static int gpmc_set_async_mode(int cs, struct gpmc_timings *t)
+{
/* Configure GPMC for asynchronous read */
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
  GPMC_CONFIG1_DEVICESIZE_16 |
  GPMC_CONFIG1_MUXADDDATA);
 
-   err = gpmc_cs_set_timings(cs, t);
-   if (err)
-   return err;
+   return gpmc_cs_set_timings(cs, t);
+}
+
+static void omap2_onenand_set_async_mode(void __iomem *onenand_base)
+{
+   u32 reg;
 
/* Ensure sync read and sync write are disabled */
reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
reg = ~ONENAND_SYS_CFG1_SYNC_READ  ~ONENAND_SYS_CFG1_SYNC_WRITE;
writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
-
-   return 0;
 }
 
-static void set_onenand_cfg(void __iomem *onenand_base, int latency,
-   int sync_read, int sync_write, int hf, int vhf)
+static void set_onenand_cfg(void __iomem *onenand_base)
 {
u32 reg;
 
@@ -112,19 +119,19 @@ static void set_onenand_cfg(void __iomem *onenand_base, 
int latency,
reg = ~((0x7  ONENAND_SYS_CFG1_BRL_SHIFT) | (0x7  9));
reg |=  (latency  ONENAND_SYS_CFG1_BRL_SHIFT) |
ONENAND_SYS_CFG1_BL_16;
-   if (sync_read)
+   if (onenand_flags  ONENAND_FLAG_SYNCREAD)
reg |= ONENAND_SYS_CFG1_SYNC_READ;
else
reg = ~ONENAND_SYS_CFG1_SYNC_READ;
-   if (sync_write)
+   if (onenand_flags  ONENAND_FLAG_SYNCWRITE)
reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
else
reg = ~ONENAND_SYS_CFG1_SYNC_WRITE;
-   if (hf)
+   if (onenand_flags  ONENAND_FLAG_HF)
reg |= ONENAND_SYS_CFG1_HF;
else
reg = ~ONENAND_SYS_CFG1_HF;
-   if (vhf)
+   if (onenand_flags  ONENAND_FLAG_VHF)
reg |= ONENAND_SYS_CFG1_VHF;
else
reg = ~ONENAND_SYS_CFG1_VHF;
@@ -172,9 +179,9 @@ static int omap2_onenand_get_freq(struct 
omap_onenand_platform_data *cfg,
return freq;
 }
 
-static int omap2_onenand_set_sync_mode(struct

[PATCH] cpufreq: OMAP: specify range for voltage scaling

2012-02-23 Thread Afzal Mohammed
Specify voltage in ranges for regulator. Range
used is tolerance specified for OPP.

This helps to achieve DVFS with a wider range of
regulators.

Cc: Kevin Hilman khil...@ti.com
Cc: Sekhar Nori nsek...@ti.com
Signed-off-by: Afzal Mohammed af...@ti.com
---
Hi,

Tolerance specified here is that of AM335X, least value
of tolerance that I could find so far for OMAP family

This applies on top of Kevin Hilman's patch (v2),
cpufreq: OMAP: scale voltage along with frequency
http://www.spinics.net/lists/linux-omap/msg65002.html

Regards
Afzal

 drivers/cpufreq/omap-cpufreq.c |   10 +++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index 10b8e23..3cea51b 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -38,6 +38,9 @@
 
 #include mach/hardware.h
 
+/* OPP tolerance in percentage */
+#defineOPP_TOLERANCE   4
+
 #ifdef CONFIG_SMP
 struct lpj_info {
unsigned long   ref;
@@ -81,7 +84,7 @@ static int omap_target(struct cpufreq_policy *policy,
int r, ret = 0;
struct cpufreq_freqs freqs;
struct opp *opp;
-   unsigned long freq, volt = 0, volt_old = 0;
+   unsigned long freq, volt = 0, volt_old = 0, tol = 0;
 
if (!freq_table) {
dev_err(mpu_dev, %s: cpu%d: no freq table!\n, __func__,
@@ -125,6 +128,7 @@ static int omap_target(struct cpufreq_policy *policy,
return -EINVAL;
}
volt = opp_get_voltage(opp);
+   tol = volt * OPP_TOLERANCE / 100;
volt_old = regulator_get_voltage(mpu_reg);
}
 
@@ -134,7 +138,7 @@ static int omap_target(struct cpufreq_policy *policy,
 
/* scaling up?  scale voltage before frequency */
if (mpu_reg  (freqs.new  freqs.old)) {
-   r = regulator_set_voltage(mpu_reg, volt, volt);
+   r = regulator_set_voltage(mpu_reg, volt - tol, volt + tol);
if (r  0) {
dev_warn(mpu_dev, %s: unable to scale voltage up.\n,
 __func__);
@@ -147,7 +151,7 @@ static int omap_target(struct cpufreq_policy *policy,
 
/* scaling down?  scale voltage after frequency */
if (mpu_reg  (freqs.new  freqs.old)) {
-   r = regulator_set_voltage(mpu_reg, volt, volt);
+   r = regulator_set_voltage(mpu_reg, volt - tol, volt + tol);
if (r  0) {
dev_warn(mpu_dev, %s: unable to scale voltage down.\n,
 __func__);
-- 
1.7.1

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


[RFC][PATCH 0/5] Convert GPMC to driver

2012-03-23 Thread Afzal Mohammed
Hi,

Convert GPCM code to be a driver. Existing GPMC
NAND platform handling has been modified to work
with the new GPMC driver (patches 2  3). Patch 5
is to test the driver in OMAP3EVM.

Once all the users has been converted to use this
driver, would be converted to MFD type.

TODO:
1. Let OMAP NAND driver deal with GPMC NAND block
2. Remove struct gpmc * stored as static
3. Convert all peripherals to use GPMC driver
4. Devise method to handle OneNAND cleanly
5. Handle acquiring CS# cases
6. Convert to MFD driver

Regards
Afzal

Afzal Mohammed (5):
  ARM: OMAP2+: gpmc: driver conversion
  ARM: OMAP2+: nand: create platform data structure
  ARM: OMAP2+: gpmc-nand: populate gpmc configs
  mtd: nand: omap2: obtain memory from resource
  OMAP3EVM: Test gpmc-nand

 arch/arm/mach-omap2/board-devkit8000.c |6 +-
 arch/arm/mach-omap2/board-flash.c  |   63 +-
 arch/arm/mach-omap2/board-flash.h  |   13 +-
 arch/arm/mach-omap2/board-ldp.c|4 +-
 arch/arm/mach-omap2/board-omap3beagle.c|6 +-
 arch/arm/mach-omap2/board-omap3evm.c   |   82 +++
 arch/arm/mach-omap2/board-omap3touchbook.c |6 +-
 arch/arm/mach-omap2/board-overo.c  |5 +-
 arch/arm/mach-omap2/board-zoom.c   |5 +-
 arch/arm/mach-omap2/common-board-devices.c |   46 --
 arch/arm/mach-omap2/common-board-devices.h |1 -
 arch/arm/mach-omap2/gpmc-nand.c|   88 +--
 arch/arm/mach-omap2/gpmc.c | 1083 
 arch/arm/plat-omap/include/plat/gpmc.h |   34 +-
 arch/arm/plat-omap/include/plat/nand.h |9 +-
 drivers/mtd/nand/omap2.c   |   19 +-
 16 files changed, 869 insertions(+), 601 deletions(-)

-- 
1.7.9.3

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


[RFC][PATCH 1/5] ARM: OMAP2+: gpmc: driver conversion

2012-03-23 Thread Afzal Mohammed
Convert GPMC code to driver. Boards using GPMC
should provide driver with type of configuration,
timing, GPMC address space details (if already
configured, driver will retrieve, as is existing).
Platform devices would the be created for each
connected peripheral (peripheral details also to
be passed by board so that it reaches respective
driver). And GPMC driver would populate memory
resource details for the driver of connected
peripheral.

A peripheral connected to GPMC can have multiple
address spaces using different chip select. Hence
GPMC driver has been provided capability to
distinguish this scenario, i.e. create platform
devices only once for each connected peripheral,
and not for each configured chip select. The
peripheral that made it necessary was tusb6010.

Final destination aimed for this driver is MFD.
But before that all existing GPMC users has to be
converted to work with this driver. This would
likely result in removal of gpmc_create_child
and probably use MFD APIs instead.

NAND driver for GPMC is tightly coupled with GPMC
driver (GPMC has few blocks exclusively for NAND),
while that is not the case for most of the other
users (they need GPMCs help only for initial
configuration). Currently NAND driver manage using
exported GPMC symbols. This is being planned to
remove later  would need informing NAND driver
about GPMC NAND registers. This would help to have
export symbol free GPMC driver, and probably
mv omap2.c gpmc-nand.c for OMAP NAND driver.
Thanks to Vaibhav Hiremath for his ideas on this.

Acquiring CS# for NAND is done on a few boards.
It means, depending on bootloader to embed this
information. Probably CS# being used can be set
in the Kernel, and acquiring it can be removed.
If ever this capbility is needed, GPMC driver
has to be made aware of handling it.

OneNAND - as it may involve reconfiguring GPMC for
synchronous may need a quirk to handle or driver
has to be made more intelligent to handle it.

Code below comment GPMC CLK related may have
to continue live in platform folders (even if the
driver is moved to MFD) as input clock is beyond
the control of GPMC and calculating timing for
the peripheral may need other helpers.

TODO (or not?)
1. NAND driver deal with GPMC NAND block
2. Remove struct gpmc * stored as static
3. Convert all peripherals to use GPMC driver
4. Devise method to handle OneNAND cleanly
5. Handle acquiring CS# cases
6. Convert to MFD driver

Signed-off-by: Afzal Mohammed af...@ti.com
Cc: Vaibhav Hiremath hvaib...@ti.com
---
 arch/arm/mach-omap2/gpmc.c | 1083 +++-
 arch/arm/plat-omap/include/plat/gpmc.h |   34 +-
 2 files changed, 672 insertions(+), 445 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 00d5108..954fa22 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -14,8 +14,11 @@
  */
 #undef DEBUG
 
+#include linux/platform_device.h
+
 #include linux/irq.h
 #include linux/kernel.h
+#include linux/slab.h
 #include linux/init.h
 #include linux/err.h
 #include linux/clk.h
@@ -64,248 +67,99 @@
 #define ENABLE_PREFETCH(0x1  7)
 #define DMA_MPU_MODE   2
 
-/* Structure to save gpmc cs context */
-struct gpmc_cs_config {
-   u32 config1;
-   u32 config2;
-   u32 config3;
-   u32 config4;
-   u32 config5;
-   u32 config6;
-   u32 config7;
-   int is_valid;
-};
-
-/*
- * Structure to save/restore gpmc context
- * to support core off on OMAP3
- */
-struct omap3_gpmc_regs {
-   u32 sysconfig;
-   u32 irqenable;
-   u32 timeout_ctrl;
-   u32 config;
-   u32 prefetch_config1;
-   u32 prefetch_config2;
-   u32 prefetch_control;
-   struct gpmc_cs_config cs_context[GPMC_CS_NUM];
-};
-
-static struct resource gpmc_mem_root;
-static struct resource gpmc_cs_mem[GPMC_CS_NUM];
-static DEFINE_SPINLOCK(gpmc_mem_lock);
-static unsigned int gpmc_cs_map;   /* flag for cs which are initialized */
-static int gpmc_ecc_used = -EINVAL;/* cs using ecc engine */
-
-static void __iomem *gpmc_base;
-
-static struct clk *gpmc_l3_clk;
-
-static irqreturn_t gpmc_handle_irq(int irq, void *dev);
 
-static void gpmc_write_reg(int idx, u32 val)
-{
-   __raw_writel(val, gpmc_base + idx);
-}
-
-static u32 gpmc_read_reg(int idx)
-{
-   return __raw_readl(gpmc_base + idx);
-}
-
-static void gpmc_cs_write_byte(int cs, int idx, u8 val)
-{
-   void __iomem *reg_addr;
+#defineDRIVER_NAME omap-gpmc
 
-   reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx;
-   __raw_writeb(val, reg_addr);
-}
+struct gpmc_child {
+   char*name;
+   int id;
+   struct resource *res;
+   unsignednum_res;
+   struct resource gpmc_res[GPMC_CS_NUM];
+   unsignedgpmc_num_res;
+   void*pdata;
+   unsignedpdata_size

[RFC][PATCH 2/5] ARM: OMAP2+: nand: create platform data structure

2012-03-23 Thread Afzal Mohammed
New API for updating nand platform data. This has
been created by unifying the two existing ones and
taking out gpmc hardware handling.

From now on, platforms can call omap_nand_init to
initialize platform nand structures, it's fields.
Or can statically create the same.

Acquiring gpmc CS has been removed. Acquiring CS
probably should be avoided, if ever required, do
in GPMC driver.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-devkit8000.c |6 ++-
 arch/arm/mach-omap2/board-flash.c  |   63 ++--
 arch/arm/mach-omap2/board-flash.h  |   13 --
 arch/arm/mach-omap2/board-ldp.c|4 +-
 arch/arm/mach-omap2/board-omap3beagle.c|6 ++-
 arch/arm/mach-omap2/board-omap3touchbook.c |6 ++-
 arch/arm/mach-omap2/board-overo.c  |5 ++-
 arch/arm/mach-omap2/board-zoom.c   |5 ++-
 arch/arm/mach-omap2/common-board-devices.c |   46 
 arch/arm/mach-omap2/common-board-devices.h |1 -
 10 files changed, 61 insertions(+), 94 deletions(-)

diff --git a/arch/arm/mach-omap2/board-devkit8000.c 
b/arch/arm/mach-omap2/board-devkit8000.c
index 11cd2a8..1a9ce9d 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -59,6 +59,7 @@
 
 #include mux.h
 #include hsmmc.h
+#include board-flash.h
 #include common-board-devices.h
 
 #define OMAP_DM9000_GPIO_IRQ   25
@@ -648,8 +649,9 @@ static void __init devkit8000_init(void)
 
usb_musb_init(NULL);
usbhs_init(usbhs_bdata);
-   omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions,
-ARRAY_SIZE(devkit8000_nand_partitions));
+   omap_nand_init(devkit8000_nand_partitions,
+   ARRAY_SIZE(devkit8000_nand_partitions), GPMC_CS_NUM + 1,
+   NAND_BUSWIDTH_16, NULL);
 
/* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal(sdrc_cke0, OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-flash.c 
b/arch/arm/mach-omap2/board-flash.c
index 0349fd2..26c70b8 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -108,45 +108,45 @@ __init board_onenand_init(struct mtd_partition 
*nor_parts, u8 nr_parts, u8 cs)
defined(CONFIG_MTD_NAND_OMAP2_MODULE)
 
 /* Note that all values in this struct are in nanoseconds */
-static struct gpmc_timings nand_timings = {
+struct gpmc_timings nand_default_timings[1] = {
+   {
+   .sync_clk = 0,
 
-   .sync_clk = 0,
+   .cs_on = 0,
+   .cs_rd_off = 36,
+   .cs_wr_off = 36,
 
-   .cs_on = 0,
-   .cs_rd_off = 36,
-   .cs_wr_off = 36,
+   .adv_on = 6,
+   .adv_rd_off = 24,
+   .adv_wr_off = 36,
 
-   .adv_on = 6,
-   .adv_rd_off = 24,
-   .adv_wr_off = 36,
+   .we_off = 30,
+   .oe_off = 48,
 
-   .we_off = 30,
-   .oe_off = 48,
+   .access = 54,
+   .rd_cycle = 72,
+   .wr_cycle = 72,
 
-   .access = 54,
-   .rd_cycle = 72,
-   .wr_cycle = 72,
-
-   .wr_access = 30,
-   .wr_data_mux_bus = 0,
+   .wr_access = 30,
+   .wr_data_mux_bus = 0,
+   },
 };
 
-static struct omap_nand_platform_data board_nand_data = {
-   .gpmc_t = nand_timings,
+static struct omap_nand_platform_data omap_nand_data = {
+   .gpmc_t = nand_default_timings,
 };
 
-void
-__init board_nand_init(struct mtd_partition *nand_parts,
-   u8 nr_parts, u8 cs, int nand_type)
+struct omap_nand_platform_data *
+__init omap_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
+   int nand_type, struct gpmc_timings *gpmc_t)
 {
-   board_nand_data.cs  = cs;
-   board_nand_data.parts   = nand_parts;
-   board_nand_data.nr_parts= nr_parts;
-   board_nand_data.devsize = nand_type;
-
-   board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
-   board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs;
-   gpmc_nand_init(board_nand_data);
+   omap_nand_data.cs   = cs;
+   omap_nand_data.parts= nand_parts;
+   omap_nand_data.nr_parts = nr_parts;
+   omap_nand_data.devsize  = nand_type;
+   omap_nand_data.gpmc_t   = gpmc_t;
+
+   return omap_nand_data;
 }
 #endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */
 
@@ -242,6 +242,7 @@ void __init board_flash_init(struct flash_partitions 
partition_info[],
if (nandcs  GPMC_CS_NUM)
pr_err(NAND: Unable to find configuration in GPMC\n);
else
-   board_nand_init(partition_info[2].parts,
-   partition_info[2].nr_parts, nandcs, nand_type);
+   omap_nand_init(partition_info[2].parts

[RFC][PATCH 3/5] ARM: OMAP2+: gpmc-nand: populate gpmc configs

2012-03-23 Thread Afzal Mohammed
Currently gpmc is configured in platform for nand.
As configuring gpmc has been moved to gpmc driver,
populate details needed for the driver to configure
gpmc. gpmc driver would configure based on this
information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc-nand.c|   88 
 arch/arm/plat-omap/include/plat/nand.h |8 +--
 2 files changed, 39 insertions(+), 57 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 386dec8..acec0ea 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -21,24 +21,29 @@
 #include plat/board.h
 #include plat/gpmc.h
 
-static struct resource gpmc_nand_resource = {
-   .flags  = IORESOURCE_MEM,
+
+#defineGPMC_NAND_CONFIG_NUM3
+
+static struct gpmc_config gpmc_nand_config[GPMC_NAND_CONFIG_NUM] = {
+   { GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND},
 };
 
-static struct platform_device gpmc_nand_device = {
+static struct gpmc_device_pdata gpmc_nand_info = {
.name   = omap2-nand,
.id = 0,
-   .num_resources  = 1,
-   .resource   = gpmc_nand_resource,
+   .config = gpmc_nand_config,
+   .num_config = ARRAY_SIZE(gpmc_nand_config),
 };
 
-static int omap2_nand_gpmc_retime(struct omap_nand_platform_data 
*gpmc_nand_data)
-{
-   struct gpmc_timings t;
-   int err;
+static struct gpmc_timings t;
 
-   if (!gpmc_nand_data-gpmc_t)
+static struct gpmc_timings *
+gpmc_nand_retime(struct omap_nand_platform_data *gpmc_nand_data)
+{
+   if (!gpmc_nand_data-gpmc_t) {
+   pr_warn(gpmc timings not provided\n);
return 0;
+   }
 
memset(t, 0, sizeof(t));
t.sync_clk = gpmc_nand_data-gpmc_t-sync_clk;
@@ -68,56 +73,31 @@ static int omap2_nand_gpmc_retime(struct 
omap_nand_platform_data *gpmc_nand_data
t.cs_wr_off = gpmc_round_ns_to_ticks(gpmc_nand_data-gpmc_t-cs_wr_off);
t.wr_cycle  = gpmc_round_ns_to_ticks(gpmc_nand_data-gpmc_t-wr_cycle);
 
-   /* Configure GPMC */
-   if (gpmc_nand_data-devsize == NAND_BUSWIDTH_16)
-   gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_DEV_SIZE, 1);
-   else
-   gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_DEV_SIZE, 0);
-   gpmc_cs_configure(gpmc_nand_data-cs,
-   GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND);
-   err = gpmc_cs_set_timings(gpmc_nand_data-cs, t);
-   if (err)
-   return err;
-
-   return 0;
+   return t;
 }
 
-int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data)
+struct gpmc_device_pdata *
+__init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data)
 {
-   int err = 0;
-   struct device *dev = gpmc_nand_device.dev;
+   gpmc_nand_info.pdata = gpmc_nand_data;
+   gpmc_nand_info.pdata_size = sizeof(*gpmc_nand_data);
 
-   gpmc_nand_device.dev.platform_data = gpmc_nand_data;
+   gpmc_nand_info.cs = gpmc_nand_data-cs;
+   gpmc_nand_info.mem_size = NAND_IO_SIZE;
 
-   err = gpmc_cs_request(gpmc_nand_data-cs, NAND_IO_SIZE,
-   gpmc_nand_data-phys_base);
-   if (err  0) {
-   dev_err(dev, Cannot request GPMC CS\n);
-   return err;
-   }
+   gpmc_nand_info.timing = gpmc_nand_retime(gpmc_nand_data);
 
-/* Set timings in GPMC */
-   err = omap2_nand_gpmc_retime(gpmc_nand_data);
-   if (err  0) {
-   dev_err(dev, Unable to set gpmc timings: %d\n, err);
-   return err;
-   }
-
-   /* Enable RD PIN Monitoring Reg */
-   if (gpmc_nand_data-dev_ready) {
-   gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_RDY_BSY, 1);
-   }
-
-   err = platform_device_register(gpmc_nand_device);
-   if (err  0) {
-   dev_err(dev, Unable to register NAND device\n);
-   goto out_free_cs;
-   }
-
-   return 0;
+   gpmc_nand_config[1].cmd = GPMC_CONFIG_DEV_SIZE;
+   if (gpmc_nand_data-devsize == NAND_BUSWIDTH_16)
+   gpmc_nand_config[1].val = 1;
+   else
+   gpmc_nand_config[1].val = 0;
 
-out_free_cs:
-   gpmc_cs_free(gpmc_nand_data-cs);
+   gpmc_nand_config[2].cmd = GPMC_CONFIG_RDY_BSY;
+   if (gpmc_nand_data-dev_ready)
+   gpmc_nand_config[2].val = 1;
+   else
+   gpmc_nand_config[2].val = 0;
 
-   return err;
+   return gpmc_nand_info;
 }
diff --git a/arch/arm/plat-omap/include/plat/nand.h 
b/arch/arm/plat-omap/include/plat/nand.h
index 67fc506..d2daeba 100644
--- a/arch/arm/plat-omap/include/plat/nand.h
+++ b/arch/arm/plat-omap/include/plat/nand.h
@@ -35,10 +35,12 @@ struct omap_nand_platform_data {
 #defineNAND_IO_SIZE4
 
 #if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
-extern int gpmc_nand_init(struct omap_nand_platform_data

[RFC][PATCH 4/5] mtd: nand: omap2: obtain memory from resource

2012-03-23 Thread Afzal Mohammed
gpmc being converted to driver, provides drivers
of peripheral connected memory space used by the
peripheral as memory resource.

Modify nand omap driver to obtain memory detials
from resource structure.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/plat-omap/include/plat/nand.h |1 -
 drivers/mtd/nand/omap2.c   |   19 +++
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/nand.h 
b/arch/arm/plat-omap/include/plat/nand.h
index d2daeba..fa49fc4 100644
--- a/arch/arm/plat-omap/include/plat/nand.h
+++ b/arch/arm/plat-omap/include/plat/nand.h
@@ -26,7 +26,6 @@ struct omap_nand_platform_data {
booldev_ready;
int gpmc_irq;
enum nand_ioxfer_type;
-   unsigned long   phys_base;
int devsize;
enum omap_ecc   ecc_opt;
 };
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index b3a883e..f6c018e 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -118,6 +118,7 @@ struct omap_nand_info {
 
int gpmc_cs;
unsigned long   phys_base;
+   unsigned long   mem_size;
struct completion   comp;
int dma_ch;
int gpmc_irq;
@@ -931,6 +932,7 @@ static int __devinit omap_nand_probe(struct platform_device 
*pdev)
struct omap_nand_platform_data  *pdata;
int err;
int i, offset;
+   struct resource *res;
 
pdata = pdev-dev.platform_data;
if (pdata == NULL) {
@@ -950,7 +952,6 @@ static int __devinit omap_nand_probe(struct platform_device 
*pdev)
info-pdev = pdev;
 
info-gpmc_cs   = pdata-cs;
-   info-phys_base = pdata-phys_base;
 
info-mtd.priv  = info-nand;
info-mtd.name  = dev_name(pdev-dev);
@@ -962,13 +963,23 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
/* NAND write protect off */
gpmc_cs_configure(info-gpmc_cs, GPMC_CONFIG_WP, 0);
 
-   if (!request_mem_region(info-phys_base, NAND_IO_SIZE,
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   if (res == NULL) {
+   err = -EINVAL;
+   dev_err(pdev-dev, error getting memory resource\n);
+   goto out_free_info;
+   }
+
+   info-phys_base = res-start;
+   info-mem_size = resource_size(res);
+
+   if (!request_mem_region(info-phys_base, info-mem_size,
pdev-dev.driver-name)) {
err = -EBUSY;
goto out_free_info;
}
 
-   info-nand.IO_ADDR_R = ioremap(info-phys_base, NAND_IO_SIZE);
+   info-nand.IO_ADDR_R = ioremap(info-phys_base, info-mem_size);
if (!info-nand.IO_ADDR_R) {
err = -ENOMEM;
goto out_release_mem_region;
@@ -1109,7 +1120,7 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
return 0;
 
 out_release_mem_region:
-   release_mem_region(info-phys_base, NAND_IO_SIZE);
+   release_mem_region(info-phys_base, info-mem_size);
 out_free_info:
kfree(info);
 
-- 
1.7.9.3

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


[TMP][PATCH 5/5] OMAP3EVM: Test gpmc-nand

2012-03-23 Thread Afzal Mohammed
Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-omap3evm.c |   82 ++
 1 file changed, 82 insertions(+)

diff --git a/arch/arm/mach-omap2/board-omap3evm.c 
b/arch/arm/mach-omap2/board-omap3evm.c
index a659e19..9ed48d4 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -23,6 +23,7 @@
 #include linux/input/matrix_keypad.h
 #include linux/leds.h
 #include linux/interrupt.h
+#include linux/mtd/nand.h
 
 #include linux/spi/spi.h
 #include linux/spi/ads7846.h
@@ -41,6 +42,7 @@
 #include asm/mach/arch.h
 #include asm/mach/map.h
 
+#include plat/nand.h
 #include plat/board.h
 #include plat/usb.h
 #include common.h
@@ -52,6 +54,7 @@
 #include sdram-micron-mt46h32m32lf-6.h
 #include hsmmc.h
 #include common-board-devices.h
+#include board-flash.h
 
 #define OMAP3_EVM_TS_GPIO  175
 #define OMAP3_EVM_EHCI_VBUS22
@@ -102,6 +105,9 @@ static void __init omap3_evm_get_revision(void)
}
 }
 
+#undef CONFIG_SMSC911X
+#undef CONFIG_SMSC911X_MODULE
+
 #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
 #include plat/gpmc-smsc911x.h
 
@@ -533,6 +539,41 @@ static struct usbhs_omap_board_data usbhs_bdata __initdata 
= {
.reset_gpio_port[2]  = -EINVAL
 };
 
+/*
+ * NAND
+ */
+static struct mtd_partition omap3_evm_nand_partitions[] = {
+   /* All the partition sizes are listed in terms of NAND block size */
+   {
+   .name   = X-Loader-NAND,
+   .offset = 0,
+   .size   = 4 * (64 * 2048),
+   .mask_flags = MTD_WRITEABLE,/* force read-only */
+   },
+   {
+   .name   = U-Boot-NAND,
+   .offset = MTDPART_OFS_APPEND,   /* Offset = 0x8 */
+   .size   = 10 * (64 * 2048),
+   .mask_flags = MTD_WRITEABLE,/* force read-only */
+   },
+   {
+   .name   = Boot Env-NAND,
+
+   .offset = MTDPART_OFS_APPEND,   /* Offset = 0x1c */
+   .size   = 6 * (64 * 2048),
+   },
+   {
+   .name   = Kernel-NAND,
+   .offset = MTDPART_OFS_APPEND,   /* Offset = 0x28 */
+   .size   = 40 * (64 * 2048),
+   },
+   {
+   .name   = File System - NAND,
+   .size   = MTDPART_SIZ_FULL,
+   .offset = MTDPART_OFS_APPEND,   /* Offset = 0x78 */
+   },
+};
+
 #ifdef CONFIG_OMAP_MUX
 static struct omap_board_mux omap35x_board_mux[] __initdata = {
OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP |
@@ -632,8 +673,30 @@ static void __init omap3_evm_wl12xx_init(void)
 #endif
 }
 
+static struct gpmc_pdata gpmc_data;
+
+static struct resource gpmc_resources[] = {
+   {
+   .start = OMAP34XX_GPMC_BASE,
+   .end   = OMAP34XX_GPMC_BASE + SZ_4K - 1,
+   .flags = IORESOURCE_MEM,
+   },
+};
+
+static struct platform_device gpmc_device = {
+   .name   = omap-gpmc,
+   .id = -1,
+   .num_resources  = ARRAY_SIZE(gpmc_resources),
+   .resource   = gpmc_resources,
+   .dev= {
+   .platform_data = gpmc_data,
+   }
+};
+
 static void __init omap3_evm_init(void)
 {
+   struct omap_nand_platform_data *nand_data;
+
omap3_evm_get_revision();
 
if (cpu_is_omap3630())
@@ -684,6 +747,25 @@ static void __init omap3_evm_init(void)
omap3evm_init_smsc911x();
omap3_evm_display_init();
omap3_evm_wl12xx_init();
+   /* NAND */
+   nand_data = omap_nand_init(omap3_evm_nand_partitions,
+   ARRAY_SIZE(omap3_evm_nand_partitions),
+   0, NAND_BUSWIDTH_16, nand_default_timings);
+   if (nand_data == NULL) {
+   pr_err(omap_nand_init() failed\n);
+   return;
+   }
+
+   gpmc_data.device_pdata = gpmc_nand_init(nand_data);
+   if (gpmc_data.device_pdata == NULL) {
+   pr_err(gpmc_nand_init() failed\n);
+   return;
+   }
+
+   gpmc_data.num_device++;
+   gpmc_data.fclk_rate = gpmc_get_fclk_period();
+
+   platform_device_register(gpmc_device);
 }
 
 MACHINE_START(OMAP3EVM, OMAP3 EVM)
-- 
1.7.9.3

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


[RFC][PATCH v2 0/5] Convert GPMC to driver

2012-03-26 Thread Afzal Mohammed

Hi,

Convert GPCM code to be a driver. Existing GPMC
NAND platform handling has been modified to work
with the new GPMC driver (patches 2  3). Patch 5
is to test the driver in OMAP3EVM.

TODO
1. Let NAND driver deal with GPMC NAND block
2. Remove struct gpmc * stored as static
3. Convert all peripherals to use GPMC driver
4. Devise method to handle OneNAND cleanly
5. Handle acquiring CS# cases
6. Decide on where GPMC driver should live
7. Adapt to HWMOD, use RPM
8. GPMC driver cleanup

Regards
Afzal

Afzal Mohammed (5):
  ARM: OMAP2+: gpmc: driver conversion
  ARM: OMAP2+: nand: create platform data structure
  ARM: OMAP2+: gpmc-nand: populate gpmc configs
  mtd: nand: omap2: obtain memory from resource
  OMAP3EVM: Test gpmc-nand

v2: Avoid code movement that kept similar code together (for easy review)

 arch/arm/mach-omap2/board-devkit8000.c |6 +-
 arch/arm/mach-omap2/board-flash.c  |   63 ++---
 arch/arm/mach-omap2/board-flash.h  |   13 +-
 arch/arm/mach-omap2/board-ldp.c|4 +-
 arch/arm/mach-omap2/board-omap3beagle.c|6 +-
 arch/arm/mach-omap2/board-omap3evm.c   |   82 +++
 arch/arm/mach-omap2/board-omap3touchbook.c |6 +-
 arch/arm/mach-omap2/board-overo.c  |5 +-
 arch/arm/mach-omap2/board-zoom.c   |5 +-
 arch/arm/mach-omap2/common-board-devices.c |   46 
 arch/arm/mach-omap2/common-board-devices.h |1 -
 arch/arm/mach-omap2/gpmc-nand.c|   88 +++
 arch/arm/mach-omap2/gpmc.c |  366 +---
 arch/arm/plat-omap/include/plat/gpmc.h |   34 ++-
 arch/arm/plat-omap/include/plat/nand.h |9 +-
 drivers/mtd/nand/omap2.c   |   19 +-
 16 files changed, 502 insertions(+), 251 deletions(-)

-- 
1.7.9.3

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


[RFC][PATCH v2 1/5] ARM: OMAP2+: gpmc: driver conversion

2012-03-26 Thread Afzal Mohammed
Convert GPMC code to driver. Boards using GPMC should provide driver
with type of configuration, timing, CS, GPMC address space details
(if already configured, driver will retrieve, as is existing).
Platform devices would the be created for each connected peripheral
(details also to be passed by board so that it reaches respective
driver). And GPMC driver would populate memory resource details for
the driver of connected peripheral.

A peripheral connected to GPMC can have multiple address spaces using
different chip select. Hence GPMC driver has been provided capability
to distinguish this scenario, i.e. create platform devices only once
for each connected peripheral, and not for each configured chip
select. The peripheral that made it necessary was tusb6010.

Final destination for this driver is being investigated. Before moving
to the new location, all existing GPMC users has to be converted to
work with this driver.

NAND driver for NAND used via GPMC is tightly coupled with GPMC
driver (GPMC has few blocks exclusively for NAND), while that is not
the case for most of the other users (they need GPMCs help only for
initial configuration). Currently NAND driver manage using exported
GPMC symbols. This is being planned to remove later  would need
informing NAND driver about GPMC NAND registers. This would help to
have export symbol free GPMC driver, and probably
mv omap2.c gpmc-nand.c for OMAP NAND driver.
Thanks to Vaibhav Hiremath for his ideas on this.

Acquiring CS# for NAND is done on a few boards. It means, depending
on bootloader to embed this information. Probably CS# being used can
be set in the Kernel, and acquiring it can be removed. If ever this
capbility is needed, GPMC driver has to be made aware of handling it.

OneNAND - as it may involve reconfiguring GPMC for synchronous may
need a quirk to handle or driver has to be made more intelligent to
handle it.

Code related to GPMC clock may have to continue live in platform
folders (even if the driver is moved to MFD) as input clock is beyond
the control of GPMC and calculating timing for the peripheral may
need other helpers.

TODO
1. Let NAND driver deal with GPMC NAND block
2. Remove struct gpmc * stored as static
3. Convert all peripherals to use GPMC driver
4. Devise method to handle OneNAND cleanly
5. Handle acquiring CS# cases
6. Decide on where GPMC driver should live
7. Adapt to HWMOD, use RPM
8. GPMC driver cleanup

Cc: Vaibhav Hiremath hvaib...@ti.com
Signed-off-by: Afzal Mohammed af...@ti.com
---
v2: Avoid code movement that kept similar code together

 arch/arm/mach-omap2/gpmc.c |  366 
 arch/arm/plat-omap/include/plat/gpmc.h |   34 ++-
 2 files changed, 305 insertions(+), 95 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 00d5108..8556153 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -14,8 +14,11 @@
  */
 #undef DEBUG
 
+#include linux/platform_device.h
+
 #include linux/irq.h
 #include linux/kernel.h
+#include linux/slab.h
 #include linux/init.h
 #include linux/err.h
 #include linux/clk.h
@@ -64,6 +67,35 @@
 #define ENABLE_PREFETCH(0x1  7)
 #define DMA_MPU_MODE   2
 
+#defineDRIVER_NAME omap-gpmc
+
+struct gpmc_child {
+   char*name;
+   int id;
+   struct resource *res;
+   unsignednum_res;
+   struct resource gpmc_res[GPMC_CS_NUM];
+   unsignedgpmc_num_res;
+   void*pdata;
+   unsignedpdata_size;
+};
+
+struct gpmc {
+   struct device   *dev;
+   unsigned long   fclk_period;
+   void __iomem*io_base;
+   unsigned long   phys_base;
+   u32 memsize;
+   unsignedcs_map;
+   int ecc_used;
+   spinlock_t  mem_lock;
+   struct resource mem_root;
+   struct resource cs_mem[GPMC_CS_NUM];
+   struct gpmc_child   child_device[GPMC_CS_NUM];
+   unsignednum_child;
+   unsignednum_device;
+};
+
 /* Structure to save gpmc cs context */
 struct gpmc_cs_config {
u32 config1;
@@ -91,58 +123,50 @@ struct omap3_gpmc_regs {
struct gpmc_cs_config cs_context[GPMC_CS_NUM];
 };
 
-static struct resource gpmc_mem_root;
-static struct resource gpmc_cs_mem[GPMC_CS_NUM];
-static DEFINE_SPINLOCK(gpmc_mem_lock);
-static unsigned int gpmc_cs_map;   /* flag for cs which are initialized */
-static int gpmc_ecc_used = -EINVAL;/* cs using ecc engine */
-
-static void __iomem *gpmc_base;
-
 static struct clk *gpmc_l3_clk;
 
-static irqreturn_t gpmc_handle_irq(int irq, void *dev);
+static struct gpmc *gpmc;
 
 static void gpmc_write_reg(int idx, u32 val)
 {
-   __raw_writel(val, gpmc_base + idx);
+   writel(val, gpmc-io_base

[RFC][PATCH v2 2/5] ARM: OMAP2+: nand: create platform data structure

2012-03-26 Thread Afzal Mohammed
New API for updating nand platform data. This has
been created by unifying the two existing ones and
taking out gpmc hardware handling.

From now on, platforms can call omap_nand_init to
initialize platform nand structures, it's fields.
Or can statically create the same.

Acquiring gpmc CS has been removed. Acquiring CS
probably should be avoided, if ever required, do
in GPMC driver.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-devkit8000.c |6 ++-
 arch/arm/mach-omap2/board-flash.c  |   63 ++--
 arch/arm/mach-omap2/board-flash.h  |   13 --
 arch/arm/mach-omap2/board-ldp.c|4 +-
 arch/arm/mach-omap2/board-omap3beagle.c|6 ++-
 arch/arm/mach-omap2/board-omap3touchbook.c |6 ++-
 arch/arm/mach-omap2/board-overo.c  |5 ++-
 arch/arm/mach-omap2/board-zoom.c   |5 ++-
 arch/arm/mach-omap2/common-board-devices.c |   46 
 arch/arm/mach-omap2/common-board-devices.h |1 -
 10 files changed, 61 insertions(+), 94 deletions(-)

diff --git a/arch/arm/mach-omap2/board-devkit8000.c 
b/arch/arm/mach-omap2/board-devkit8000.c
index 11cd2a8..1a9ce9d 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -59,6 +59,7 @@
 
 #include mux.h
 #include hsmmc.h
+#include board-flash.h
 #include common-board-devices.h
 
 #define OMAP_DM9000_GPIO_IRQ   25
@@ -648,8 +649,9 @@ static void __init devkit8000_init(void)
 
usb_musb_init(NULL);
usbhs_init(usbhs_bdata);
-   omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions,
-ARRAY_SIZE(devkit8000_nand_partitions));
+   omap_nand_init(devkit8000_nand_partitions,
+   ARRAY_SIZE(devkit8000_nand_partitions), GPMC_CS_NUM + 1,
+   NAND_BUSWIDTH_16, NULL);
 
/* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal(sdrc_cke0, OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-flash.c 
b/arch/arm/mach-omap2/board-flash.c
index 0349fd2..26c70b8 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -108,45 +108,45 @@ __init board_onenand_init(struct mtd_partition 
*nor_parts, u8 nr_parts, u8 cs)
defined(CONFIG_MTD_NAND_OMAP2_MODULE)
 
 /* Note that all values in this struct are in nanoseconds */
-static struct gpmc_timings nand_timings = {
+struct gpmc_timings nand_default_timings[1] = {
+   {
+   .sync_clk = 0,
 
-   .sync_clk = 0,
+   .cs_on = 0,
+   .cs_rd_off = 36,
+   .cs_wr_off = 36,
 
-   .cs_on = 0,
-   .cs_rd_off = 36,
-   .cs_wr_off = 36,
+   .adv_on = 6,
+   .adv_rd_off = 24,
+   .adv_wr_off = 36,
 
-   .adv_on = 6,
-   .adv_rd_off = 24,
-   .adv_wr_off = 36,
+   .we_off = 30,
+   .oe_off = 48,
 
-   .we_off = 30,
-   .oe_off = 48,
+   .access = 54,
+   .rd_cycle = 72,
+   .wr_cycle = 72,
 
-   .access = 54,
-   .rd_cycle = 72,
-   .wr_cycle = 72,
-
-   .wr_access = 30,
-   .wr_data_mux_bus = 0,
+   .wr_access = 30,
+   .wr_data_mux_bus = 0,
+   },
 };
 
-static struct omap_nand_platform_data board_nand_data = {
-   .gpmc_t = nand_timings,
+static struct omap_nand_platform_data omap_nand_data = {
+   .gpmc_t = nand_default_timings,
 };
 
-void
-__init board_nand_init(struct mtd_partition *nand_parts,
-   u8 nr_parts, u8 cs, int nand_type)
+struct omap_nand_platform_data *
+__init omap_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
+   int nand_type, struct gpmc_timings *gpmc_t)
 {
-   board_nand_data.cs  = cs;
-   board_nand_data.parts   = nand_parts;
-   board_nand_data.nr_parts= nr_parts;
-   board_nand_data.devsize = nand_type;
-
-   board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
-   board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs;
-   gpmc_nand_init(board_nand_data);
+   omap_nand_data.cs   = cs;
+   omap_nand_data.parts= nand_parts;
+   omap_nand_data.nr_parts = nr_parts;
+   omap_nand_data.devsize  = nand_type;
+   omap_nand_data.gpmc_t   = gpmc_t;
+
+   return omap_nand_data;
 }
 #endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */
 
@@ -242,6 +242,7 @@ void __init board_flash_init(struct flash_partitions 
partition_info[],
if (nandcs  GPMC_CS_NUM)
pr_err(NAND: Unable to find configuration in GPMC\n);
else
-   board_nand_init(partition_info[2].parts,
-   partition_info[2].nr_parts, nandcs, nand_type);
+   omap_nand_init(partition_info[2].parts

[RFC][PATCH v2 3/5] ARM: OMAP2+: gpmc-nand: populate gpmc configs

2012-03-26 Thread Afzal Mohammed
Currently gpmc is configured in platform for nand.
As configuring gpmc has been moved to gpmc driver,
populate details needed for the driver to configure
gpmc. gpmc driver would configure based on this
information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc-nand.c|   88 
 arch/arm/plat-omap/include/plat/nand.h |8 +--
 2 files changed, 39 insertions(+), 57 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 386dec8..acec0ea 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -21,24 +21,29 @@
 #include plat/board.h
 #include plat/gpmc.h
 
-static struct resource gpmc_nand_resource = {
-   .flags  = IORESOURCE_MEM,
+
+#defineGPMC_NAND_CONFIG_NUM3
+
+static struct gpmc_config gpmc_nand_config[GPMC_NAND_CONFIG_NUM] = {
+   { GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND},
 };
 
-static struct platform_device gpmc_nand_device = {
+static struct gpmc_device_pdata gpmc_nand_info = {
.name   = omap2-nand,
.id = 0,
-   .num_resources  = 1,
-   .resource   = gpmc_nand_resource,
+   .config = gpmc_nand_config,
+   .num_config = ARRAY_SIZE(gpmc_nand_config),
 };
 
-static int omap2_nand_gpmc_retime(struct omap_nand_platform_data 
*gpmc_nand_data)
-{
-   struct gpmc_timings t;
-   int err;
+static struct gpmc_timings t;
 
-   if (!gpmc_nand_data-gpmc_t)
+static struct gpmc_timings *
+gpmc_nand_retime(struct omap_nand_platform_data *gpmc_nand_data)
+{
+   if (!gpmc_nand_data-gpmc_t) {
+   pr_warn(gpmc timings not provided\n);
return 0;
+   }
 
memset(t, 0, sizeof(t));
t.sync_clk = gpmc_nand_data-gpmc_t-sync_clk;
@@ -68,56 +73,31 @@ static int omap2_nand_gpmc_retime(struct 
omap_nand_platform_data *gpmc_nand_data
t.cs_wr_off = gpmc_round_ns_to_ticks(gpmc_nand_data-gpmc_t-cs_wr_off);
t.wr_cycle  = gpmc_round_ns_to_ticks(gpmc_nand_data-gpmc_t-wr_cycle);
 
-   /* Configure GPMC */
-   if (gpmc_nand_data-devsize == NAND_BUSWIDTH_16)
-   gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_DEV_SIZE, 1);
-   else
-   gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_DEV_SIZE, 0);
-   gpmc_cs_configure(gpmc_nand_data-cs,
-   GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND);
-   err = gpmc_cs_set_timings(gpmc_nand_data-cs, t);
-   if (err)
-   return err;
-
-   return 0;
+   return t;
 }
 
-int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data)
+struct gpmc_device_pdata *
+__init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data)
 {
-   int err = 0;
-   struct device *dev = gpmc_nand_device.dev;
+   gpmc_nand_info.pdata = gpmc_nand_data;
+   gpmc_nand_info.pdata_size = sizeof(*gpmc_nand_data);
 
-   gpmc_nand_device.dev.platform_data = gpmc_nand_data;
+   gpmc_nand_info.cs = gpmc_nand_data-cs;
+   gpmc_nand_info.mem_size = NAND_IO_SIZE;
 
-   err = gpmc_cs_request(gpmc_nand_data-cs, NAND_IO_SIZE,
-   gpmc_nand_data-phys_base);
-   if (err  0) {
-   dev_err(dev, Cannot request GPMC CS\n);
-   return err;
-   }
+   gpmc_nand_info.timing = gpmc_nand_retime(gpmc_nand_data);
 
-/* Set timings in GPMC */
-   err = omap2_nand_gpmc_retime(gpmc_nand_data);
-   if (err  0) {
-   dev_err(dev, Unable to set gpmc timings: %d\n, err);
-   return err;
-   }
-
-   /* Enable RD PIN Monitoring Reg */
-   if (gpmc_nand_data-dev_ready) {
-   gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_RDY_BSY, 1);
-   }
-
-   err = platform_device_register(gpmc_nand_device);
-   if (err  0) {
-   dev_err(dev, Unable to register NAND device\n);
-   goto out_free_cs;
-   }
-
-   return 0;
+   gpmc_nand_config[1].cmd = GPMC_CONFIG_DEV_SIZE;
+   if (gpmc_nand_data-devsize == NAND_BUSWIDTH_16)
+   gpmc_nand_config[1].val = 1;
+   else
+   gpmc_nand_config[1].val = 0;
 
-out_free_cs:
-   gpmc_cs_free(gpmc_nand_data-cs);
+   gpmc_nand_config[2].cmd = GPMC_CONFIG_RDY_BSY;
+   if (gpmc_nand_data-dev_ready)
+   gpmc_nand_config[2].val = 1;
+   else
+   gpmc_nand_config[2].val = 0;
 
-   return err;
+   return gpmc_nand_info;
 }
diff --git a/arch/arm/plat-omap/include/plat/nand.h 
b/arch/arm/plat-omap/include/plat/nand.h
index 67fc506..d2daeba 100644
--- a/arch/arm/plat-omap/include/plat/nand.h
+++ b/arch/arm/plat-omap/include/plat/nand.h
@@ -35,10 +35,12 @@ struct omap_nand_platform_data {
 #defineNAND_IO_SIZE4
 
 #if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
-extern int gpmc_nand_init(struct omap_nand_platform_data

[RFC][PATCH v2 4/5] mtd: nand: omap2: obtain memory from resource

2012-03-26 Thread Afzal Mohammed
gpmc being converted to driver, provides drivers
of peripheral connected memory space used by the
peripheral as memory resource.

Modify nand omap driver to obtain memory detials
from resource structure.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/plat-omap/include/plat/nand.h |1 -
 drivers/mtd/nand/omap2.c   |   19 +++
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/nand.h 
b/arch/arm/plat-omap/include/plat/nand.h
index d2daeba..fa49fc4 100644
--- a/arch/arm/plat-omap/include/plat/nand.h
+++ b/arch/arm/plat-omap/include/plat/nand.h
@@ -26,7 +26,6 @@ struct omap_nand_platform_data {
booldev_ready;
int gpmc_irq;
enum nand_ioxfer_type;
-   unsigned long   phys_base;
int devsize;
enum omap_ecc   ecc_opt;
 };
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index b3a883e..f6c018e 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -118,6 +118,7 @@ struct omap_nand_info {
 
int gpmc_cs;
unsigned long   phys_base;
+   unsigned long   mem_size;
struct completion   comp;
int dma_ch;
int gpmc_irq;
@@ -931,6 +932,7 @@ static int __devinit omap_nand_probe(struct platform_device 
*pdev)
struct omap_nand_platform_data  *pdata;
int err;
int i, offset;
+   struct resource *res;
 
pdata = pdev-dev.platform_data;
if (pdata == NULL) {
@@ -950,7 +952,6 @@ static int __devinit omap_nand_probe(struct platform_device 
*pdev)
info-pdev = pdev;
 
info-gpmc_cs   = pdata-cs;
-   info-phys_base = pdata-phys_base;
 
info-mtd.priv  = info-nand;
info-mtd.name  = dev_name(pdev-dev);
@@ -962,13 +963,23 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
/* NAND write protect off */
gpmc_cs_configure(info-gpmc_cs, GPMC_CONFIG_WP, 0);
 
-   if (!request_mem_region(info-phys_base, NAND_IO_SIZE,
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   if (res == NULL) {
+   err = -EINVAL;
+   dev_err(pdev-dev, error getting memory resource\n);
+   goto out_free_info;
+   }
+
+   info-phys_base = res-start;
+   info-mem_size = resource_size(res);
+
+   if (!request_mem_region(info-phys_base, info-mem_size,
pdev-dev.driver-name)) {
err = -EBUSY;
goto out_free_info;
}
 
-   info-nand.IO_ADDR_R = ioremap(info-phys_base, NAND_IO_SIZE);
+   info-nand.IO_ADDR_R = ioremap(info-phys_base, info-mem_size);
if (!info-nand.IO_ADDR_R) {
err = -ENOMEM;
goto out_release_mem_region;
@@ -1109,7 +1120,7 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
return 0;
 
 out_release_mem_region:
-   release_mem_region(info-phys_base, NAND_IO_SIZE);
+   release_mem_region(info-phys_base, info-mem_size);
 out_free_info:
kfree(info);
 
-- 
1.7.9.3

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


[TMP][PATCH v2 5/5] OMAP3EVM: Test gpmc-nand

2012-03-26 Thread Afzal Mohammed
Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-omap3evm.c |   82 ++
 1 file changed, 82 insertions(+)

diff --git a/arch/arm/mach-omap2/board-omap3evm.c 
b/arch/arm/mach-omap2/board-omap3evm.c
index a659e19..2695663 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -23,6 +23,7 @@
 #include linux/input/matrix_keypad.h
 #include linux/leds.h
 #include linux/interrupt.h
+#include linux/mtd/nand.h
 
 #include linux/spi/spi.h
 #include linux/spi/ads7846.h
@@ -41,6 +42,7 @@
 #include asm/mach/arch.h
 #include asm/mach/map.h
 
+#include plat/nand.h
 #include plat/board.h
 #include plat/usb.h
 #include common.h
@@ -52,6 +54,7 @@
 #include sdram-micron-mt46h32m32lf-6.h
 #include hsmmc.h
 #include common-board-devices.h
+#include board-flash.h
 
 #define OMAP3_EVM_TS_GPIO  175
 #define OMAP3_EVM_EHCI_VBUS22
@@ -102,6 +105,9 @@ static void __init omap3_evm_get_revision(void)
}
 }
 
+#undef CONFIG_SMSC911X
+#undef CONFIG_SMSC911X_MODULE
+
 #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
 #include plat/gpmc-smsc911x.h
 
@@ -533,6 +539,41 @@ static struct usbhs_omap_board_data usbhs_bdata __initdata 
= {
.reset_gpio_port[2]  = -EINVAL
 };
 
+/*
+ * NAND
+ */
+static struct mtd_partition omap3_evm_nand_partitions[] = {
+   /* All the partition sizes are listed in terms of NAND block size */
+   {
+   .name   = X-Loader-NAND,
+   .offset = 0,
+   .size   = 4 * (64 * 2048),
+   .mask_flags = MTD_WRITEABLE,/* force read-only */
+   },
+   {
+   .name   = U-Boot-NAND,
+   .offset = MTDPART_OFS_APPEND,   /* Offset = 0x8 */
+   .size   = 10 * (64 * 2048),
+   .mask_flags = MTD_WRITEABLE,/* force read-only */
+   },
+   {
+   .name   = Boot Env-NAND,
+
+   .offset = MTDPART_OFS_APPEND,   /* Offset = 0x1c */
+   .size   = 6 * (64 * 2048),
+   },
+   {
+   .name   = Kernel-NAND,
+   .offset = MTDPART_OFS_APPEND,   /* Offset = 0x28 */
+   .size   = 40 * (64 * 2048),
+   },
+   {
+   .name   = File System - NAND,
+   .size   = MTDPART_SIZ_FULL,
+   .offset = MTDPART_OFS_APPEND,   /* Offset = 0x78 */
+   },
+};
+
 #ifdef CONFIG_OMAP_MUX
 static struct omap_board_mux omap35x_board_mux[] __initdata = {
OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP |
@@ -632,8 +673,30 @@ static void __init omap3_evm_wl12xx_init(void)
 #endif
 }
 
+static struct gpmc_pdata gpmc_data;
+
+static struct resource gpmc_resources[] = {
+   {
+   .start = OMAP34XX_GPMC_BASE,
+   .end   = OMAP34XX_GPMC_BASE + SZ_4K - 1,
+   .flags = IORESOURCE_MEM,
+   },
+};
+
+static struct platform_device gpmc_device = {
+   .name   = omap-gpmc,
+   .id = -1,
+   .num_resources  = ARRAY_SIZE(gpmc_resources),
+   .resource   = gpmc_resources,
+   .dev= {
+   .platform_data = gpmc_data,
+   }
+};
+
 static void __init omap3_evm_init(void)
 {
+   struct omap_nand_platform_data *nand_data;
+
omap3_evm_get_revision();
 
if (cpu_is_omap3630())
@@ -684,6 +747,25 @@ static void __init omap3_evm_init(void)
omap3evm_init_smsc911x();
omap3_evm_display_init();
omap3_evm_wl12xx_init();
+   /* NAND */
+   nand_data = omap_nand_init(omap3_evm_nand_partitions,
+   ARRAY_SIZE(omap3_evm_nand_partitions),
+   0, NAND_BUSWIDTH_16, nand_default_timings);
+   if (nand_data == NULL) {
+   pr_err(omap_nand_init() failed\n);
+   return;
+   }
+
+   gpmc_data.device_pdata = gpmc_nand_init(nand_data);
+   if (gpmc_data.device_pdata == NULL) {
+   pr_err(gpmc_nand_init() failed\n);
+   return;
+   }
+
+   gpmc_data.num_device++;
+   gpmc_data.fclk_period = gpmc_get_fclk_period();
+
+   platform_device_register(gpmc_device);
 }
 
 MACHINE_START(OMAP3EVM, OMAP3 EVM)
-- 
1.7.9.3

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


[PATCH v3 0/9] Convert OMAP GPMC to driver

2012-04-05 Thread Afzal Mohammed
Hi,

GPMC driver conversion series. NAND and smsc911x ethernet device has
been adapted to use GPMC driver.

Patches has been generated over linux-omap/master, HEAD
33fc21e Linux-omap rebuilt: Updated to v3.4-rc1, merged in most of pending 
branches
As OMAP3EVM does not boot linux-omap/master, merge commit,
58adb29 Merge branch 'io_chain_devel_3.4' of git://git.pwsan.com/linux-2.6 into 
prm
has to be reverted to get OMAP3EVM boot.
Last patch (with subject prefix TMP - 9/9) is for testing.

Once driver is acceptable, platform code for other peripherals
connected via GPMC would be adapted to make use of GPMC driver. And
then the board modifications. But before that HWMOD entry has to be
populated for respective SoC(s ?).



Now DESTINATION FOR THIS DRIVER has to be decided. Original plan was
to consider GPMC as MFD. The peripheral(s) connected to GPMC being
considered childs of MFD.

GPMC (General Purpose Memory Controller) in brief:
GPMC is an unified memory controller dedicated to interfacing external
memory devices like
 Asynchronous SRAM like memories and application specific integrated circuit 
devices.
 Asynchronous, synchronous, and page mode burst NOR flash devices NAND flash
 Pseudo-SRAM devices

GPMC has to be configured as required by timings of the connected
peripheral. It needs to be configured only initially (only exception
being resume afaik, where it needs to be reconfigured). Handling GPMC
cannot be left to platform code to handle, then where can it be ?
(currently it is handled by platform code). Once it is configured it
can be used to handle different protocols like NAND, NOR. Various
kinds of devices like ethernet, uart, usb, fpga etc can work using
GPMC interface. GPMC has a seperate additional functionality of
NAND handling (not manhandling ;) ). But with this series, dealing
NAND block of GPMC has been separated from GPMC driver and given
to NAND driver.

It seems decision on where a driver should go is based more on
functionality.

Any suggestions on where GPMC driver could go would be very helpful.
This would also help in reducing amount of platform code for OMAP.

Various options that could be seen so far on where this driver can go,
1. mfd
2. misc
3. drivers/platform/arm/ (create an new one?)
4. memory (create a new one ?)

If GPMC sounds similar to something else that is present in other
chips, please be kind enough to let me know how this is handled by
Kernel (if).

GPMC details can be referred in AM335X Technical Reference Manual
@ http://www.ti.com/lit/pdf/spruh73


Regards
Afzal


v3: Single device structure passed from platform for peripherals using
multiple CS instead of using multiple device structure having a few
redundant data, handle interrupts, GPMC NAND handling by GPMC NAND
driver instead of GPMC driver
v2: Avoid code movement that kept similar code together (for easy review)

TODO:
1. Decide on destination of GPMC driver
2. Modify platform code so that remaining peripherals can be
   configured using GPMC driver instead of platform code doing so.
3. Remove static struct gpmc * (could be done once all other
   peripherals are adapted to use GPMC driver)
4. Devise method to handle OneNAND for GPMC cleanly
5. Handle acquiring CS# (if required)
6. Adapt to HWMOD, use RPM
7. Cleanup (once all peripherals make use of GPMC driver all the
   exported symbols can be removed, and complete removal of a few of
   these functions would be possible, like gpmc_nand_* can be deleted
   now itself)

Afzal Mohammed (9):
  ARM: OMAP2+: gpmc: driver conversion
  ARM: OMAP2+: gpmc: registers for nand driver
  ARM: OMAP2+: nand: create platform data structure
  ARM: OMAP2+: gpmc-nand: populate gpmc configs
  ARM: OMAP2+: gpmc-smsc911x: gpmc driver information
  mtd: nand: omap2: obtain memory from resource
  mtd: nand: omap2: use gpmc provided irqs
  mtd: nand: omap2: handle nand on gpmc
  OMAP3EVM: Test gpmc-nand

 arch/arm/mach-omap2/board-devkit8000.c  |6 +-
 arch/arm/mach-omap2/board-flash.c   |   63 +--
 arch/arm/mach-omap2/board-flash.h   |   13 +-
 arch/arm/mach-omap2/board-ldp.c |4 +-
 arch/arm/mach-omap2/board-omap3beagle.c |6 +-
 arch/arm/mach-omap2/board-omap3evm.c|   95 +++-
 arch/arm/mach-omap2/board-omap3touchbook.c  |6 +-
 arch/arm/mach-omap2/board-overo.c   |5 +-
 arch/arm/mach-omap2/board-zoom.c|5 +-
 arch/arm/mach-omap2/common-board-devices.c  |   46 --
 arch/arm/mach-omap2/common-board-devices.h  |1 -
 arch/arm/mach-omap2/gpmc-nand.c |   97 ++--
 arch/arm/mach-omap2/gpmc-smsc911x.c |   59 +--
 arch/arm/mach-omap2/gpmc.c  |  543 +++
 arch/arm/plat-omap/include/plat/gpmc-smsc911x.h |9 +-
 arch/arm/plat-omap/include/plat/gpmc.h  |   66 ++-
 arch/arm/plat-omap/include/plat/nand.h  |   10 +-
 drivers/mtd/nand/omap2.c

[PATCH v3 2/9] ARM: OMAP2+: gpmc: registers for nand driver

2012-04-05 Thread Afzal Mohammed
If peripheral connected is NAND, update NAND drivers platform data
with NAND related register addresses so that NAND driver can handle
GPMC NAND operations by itself

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |   25 +
 arch/arm/plat-omap/include/plat/gpmc.h |   16 
 arch/arm/plat-omap/include/plat/nand.h |1 +
 3 files changed, 42 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index cf5d8f3..ca7fa83 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -30,6 +30,7 @@
 
 #include asm/mach-types.h
 #include plat/gpmc.h
+#include plat/nand.h
 
 #include plat/sdrc.h
 
@@ -766,6 +767,28 @@ static int __init gpmc_init(void)
 }
 postcore_initcall(gpmc_init);
 
+static __devinit void gpmc_update_nand_reg(struct gpmc *gpmc,
+   struct omap_nand_platform_data *nand)
+{
+   int cs = nand-cs;
+
+   nand-reg.gpmc_status = gpmc-io_base + GPMC_STATUS;
+   nand-reg.gpmc_nand_command = gpmc-io_base + GPMC_CS0_OFFSET +
+   GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs;
+   nand-reg.gpmc_nand_address = gpmc-io_base + GPMC_CS0_OFFSET +
+   GPMC_CS_NAND_ADDRESS + GPMC_CS_SIZE * cs;
+   nand-reg.gpmc_nand_data = gpmc-io_base + GPMC_CS0_OFFSET +
+   GPMC_CS_NAND_DATA + GPMC_CS_SIZE * cs;
+   nand-reg.gpmc_prefetch_config1 = gpmc-io_base + GPMC_PREFETCH_CONFIG1;
+   nand-reg.gpmc_prefetch_config2 = gpmc-io_base + GPMC_PREFETCH_CONFIG2;
+   nand-reg.gpmc_prefetch_control = gpmc-io_base + GPMC_PREFETCH_CONTROL;
+   nand-reg.gpmc_prefetch_status = gpmc-io_base + GPMC_PREFETCH_STATUS;
+   nand-reg.gpmc_ecc_config = gpmc-io_base + GPMC_ECC_CONFIG;
+   nand-reg.gpmc_ecc_control = gpmc-io_base + GPMC_ECC_CONTROL;
+   nand-reg.gpmc_ecc_size_config = gpmc-io_base + GPMC_ECC_SIZE_CONFIG;
+   nand-reg.gpmc_ecc1_result = gpmc-io_base + GPMC_ECC1_RESULT;
+}
+
 static __devinit struct resource gpmc_setup_cs_mem(struct gpmc_cs_data *p,
struct gpmc_device_pdata *gdp, struct gpmc *gpmc)
 {
@@ -1066,6 +1089,8 @@ static __devinit int gpmc_probe(struct platform_device 
*pdev)
gpmc_mem_init();
 
for (gdq = gp-device_pdata, gd = gpmc-device; *gdq; gdq++, i++) {
+   if ((*gdq)-is_nand)
+   gpmc_update_nand_reg(gpmc, (*gdq)-pdata);
ret = gpmc_setup_device(*gdq, gd, gpmc);
if (IS_ERR_VALUE(ret))
dev_err(gpmc-dev, gpmc setup on %s failed\n,
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h 
b/arch/arm/plat-omap/include/plat/gpmc.h
index fa62cdf..a320e71 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -169,6 +169,7 @@ struct gpmc_device_pdata {
unsignednum_per_res;
struct gpmc_cs_data *cs_data;
unsignednum_cs;
+   boolis_nand;
 };
 
 struct gpmc_pdata {
@@ -179,6 +180,21 @@ struct gpmc_pdata {
unsignednum_irq;
 };
 
+struct gpmc_nand_regs {
+   void __iomem*gpmc_status;
+   void __iomem*gpmc_nand_command;
+   void __iomem*gpmc_nand_address;
+   void __iomem*gpmc_nand_data;
+   void __iomem*gpmc_prefetch_config1;
+   void __iomem*gpmc_prefetch_config2;
+   void __iomem*gpmc_prefetch_control;
+   void __iomem*gpmc_prefetch_status;
+   void __iomem*gpmc_ecc_config;
+   void __iomem*gpmc_ecc_control;
+   void __iomem*gpmc_ecc_size_config;
+   void __iomem*gpmc_ecc1_result;
+};
+
 extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
 extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps);
 extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
diff --git a/arch/arm/plat-omap/include/plat/nand.h 
b/arch/arm/plat-omap/include/plat/nand.h
index 67fc506..86e4d9c 100644
--- a/arch/arm/plat-omap/include/plat/nand.h
+++ b/arch/arm/plat-omap/include/plat/nand.h
@@ -29,6 +29,7 @@ struct omap_nand_platform_data {
unsigned long   phys_base;
int devsize;
enum omap_ecc   ecc_opt;
+   struct gpmc_nand_regs   reg;
 };
 
 /* minimum size for IO mapping */
-- 
1.7.9.3

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


[PATCH v3 1/9] ARM: OMAP2+: gpmc: driver conversion

2012-04-05 Thread Afzal Mohammed
Convert GPMC code to driver. Boards using GPMC should provide driver
with type of configuration, timing, CS, GPMC address space details
(if already configured, driver will retrieve, as is existing).
Platform devices would the be created for each connected peripheral
(details also to be passed by board so that it reaches respective
driver). And GPMC driver would populate memory resource details for
the driver of connected peripheral.

A peripheral connected to GPMC can have multiple address spaces using
different chip select. Hence GPMC driver has been provided capability
to create platform device for peripheral using mutiple CS. The
peripheral that made it necessary was tusb6010. Thanks to Jon Hunter
for his suggesstion on better way to handle this.

Interrupts of GPMC are presented to drivers of connected peripherals
as resource. A fictitious interrupt controller chip handles these
interrupts at GPMC hardware level. Clients can use normal interrupt
APIs. Platforms should inform GPMC driver infrastruture available
for these imaginary client interrupts (like irq number). Platform
information of peripheral passed to GPMC driver should indicate
interrupts to be used via flags.

Final destination for this driver is being investigated. Before moving
to the new location, all existing GPMC users has to be converted to
work with this driver.

NAND driver for NAND used via GPMC is tightly coupled with GPMC
driver (GPMC has few blocks exclusively for NAND), while that is not
the case for most of the other users (they need GPMCs help only for
initial configuration). Currently NAND driver manage using exported
GPMC symbols. This is being planned to remove later  would need
informing NAND driver about GPMC NAND registers. This would help to
have export symbol free GPMC driver, and probably
mv omap2.c gpmc-nand.c for OMAP NAND driver.
Thanks to Vaibhav Hiremath for his ideas on this.

Acquiring CS# for NAND is done on a few boards. It means, depending
on bootloader to embed this information. Probably CS# being used can
be set in the Kernel, and acquiring it can be removed. If ever this
capbility is needed, GPMC driver has to be made aware of handling it.

OneNAND - as it may involve reconfiguring GPMC for synchronous may
need a quirk to handle or driver has to be made more intelligent to
handle it.

Code related to GPMC clock may have to continue live in platform
folders (even if the driver is moved to MFD) as input clock is beyond
the control of GPMC and calculating timing for the peripheral may
need other helpers.

Cc: Vaibhav Hiremath hvaib...@ti.com
Cc: Jon Hunter jon-hun...@ti.com
Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |  518 ++--
 arch/arm/plat-omap/include/plat/gpmc.h |   50 ++-
 2 files changed, 476 insertions(+), 92 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 00d5108..cf5d8f3 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -14,8 +14,11 @@
  */
 #undef DEBUG
 
+#include linux/platform_device.h
+
 #include linux/irq.h
 #include linux/kernel.h
+#include linux/slab.h
 #include linux/init.h
 #include linux/err.h
 #include linux/clk.h
@@ -64,6 +67,47 @@
 #define ENABLE_PREFETCH(0x1  7)
 #define DMA_MPU_MODE   2
 
+#defineDRIVER_NAME omap-gpmc
+
+#defineGPMC_NR_IRQ 6
+
+struct gpmc_device {
+   char*name;
+   int id;
+   void*pdata;
+   unsignedpdata_size;
+   struct resource *per_res;
+   unsignednum_per_res;
+   struct resource *gpmc_res;
+   unsignednum_gpmc_res;
+};
+
+struct gpmc_irq{
+   unsignedirq;
+   u32 regval;
+};
+
+struct gpmc {
+   struct device   *dev;
+   unsigned long   fclk_period;
+   void __iomem*io_base;
+   unsigned long   phys_base;
+   u32 memsize;
+   unsignedcs_map;
+   int ecc_used;
+   spinlock_t  mem_lock;
+   struct resource mem_root;
+   struct resource cs_mem[GPMC_CS_NUM];
+   /* XXX: Or allocate dynamically ? */
+   struct gpmc_device  device[GPMC_CS_NUM];
+   unsignednum_device;
+   unsignedmaster_irq;
+   unsignedirq_start;
+   unsignednum_irq;
+   struct gpmc_irq irq[GPMC_NR_IRQ];
+   struct irq_chip irq_chip;
+};
+
 /* Structure to save gpmc cs context */
 struct gpmc_cs_config {
u32 config1;
@@ -91,58 +135,50 @@ struct omap3_gpmc_regs {
struct gpmc_cs_config cs_context[GPMC_CS_NUM];
 };
 
-static struct resource gpmc_mem_root;
-static struct resource gpmc_cs_mem[GPMC_CS_NUM];
-static

[PATCH v3 3/9] ARM: OMAP2+: nand: create platform data structure

2012-04-05 Thread Afzal Mohammed
New API for updating nand platform data. This has
been created by unifying the two existing ones and
taking out gpmc hardware handling.

From now on, platforms can call omap_nand_init to
initialize platform nand structures, it's fields.
Or can statically create the same.

Acquiring gpmc CS has been removed. Acquiring CS
probably should be avoided, if ever required, do
in GPMC driver.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-devkit8000.c |6 ++-
 arch/arm/mach-omap2/board-flash.c  |   63 ++--
 arch/arm/mach-omap2/board-flash.h  |   13 --
 arch/arm/mach-omap2/board-ldp.c|4 +-
 arch/arm/mach-omap2/board-omap3beagle.c|6 ++-
 arch/arm/mach-omap2/board-omap3touchbook.c |6 ++-
 arch/arm/mach-omap2/board-overo.c  |5 ++-
 arch/arm/mach-omap2/board-zoom.c   |5 ++-
 arch/arm/mach-omap2/common-board-devices.c |   46 
 arch/arm/mach-omap2/common-board-devices.h |1 -
 10 files changed, 61 insertions(+), 94 deletions(-)

diff --git a/arch/arm/mach-omap2/board-devkit8000.c 
b/arch/arm/mach-omap2/board-devkit8000.c
index a2010f0..adfcfc1 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -59,6 +59,7 @@
 
 #include mux.h
 #include hsmmc.h
+#include board-flash.h
 #include common-board-devices.h
 
 #define OMAP_DM9000_GPIO_IRQ   25
@@ -648,8 +649,9 @@ static void __init devkit8000_init(void)
 
usb_musb_init(NULL);
usbhs_init(usbhs_bdata);
-   omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions,
-ARRAY_SIZE(devkit8000_nand_partitions));
+   omap_nand_init(devkit8000_nand_partitions,
+   ARRAY_SIZE(devkit8000_nand_partitions), GPMC_CS_NUM + 1,
+   NAND_BUSWIDTH_16, NULL);
 
/* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal(sdrc_cke0, OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-flash.c 
b/arch/arm/mach-omap2/board-flash.c
index 0349fd2..26c70b8 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -108,45 +108,45 @@ __init board_onenand_init(struct mtd_partition 
*nor_parts, u8 nr_parts, u8 cs)
defined(CONFIG_MTD_NAND_OMAP2_MODULE)
 
 /* Note that all values in this struct are in nanoseconds */
-static struct gpmc_timings nand_timings = {
+struct gpmc_timings nand_default_timings[1] = {
+   {
+   .sync_clk = 0,
 
-   .sync_clk = 0,
+   .cs_on = 0,
+   .cs_rd_off = 36,
+   .cs_wr_off = 36,
 
-   .cs_on = 0,
-   .cs_rd_off = 36,
-   .cs_wr_off = 36,
+   .adv_on = 6,
+   .adv_rd_off = 24,
+   .adv_wr_off = 36,
 
-   .adv_on = 6,
-   .adv_rd_off = 24,
-   .adv_wr_off = 36,
+   .we_off = 30,
+   .oe_off = 48,
 
-   .we_off = 30,
-   .oe_off = 48,
+   .access = 54,
+   .rd_cycle = 72,
+   .wr_cycle = 72,
 
-   .access = 54,
-   .rd_cycle = 72,
-   .wr_cycle = 72,
-
-   .wr_access = 30,
-   .wr_data_mux_bus = 0,
+   .wr_access = 30,
+   .wr_data_mux_bus = 0,
+   },
 };
 
-static struct omap_nand_platform_data board_nand_data = {
-   .gpmc_t = nand_timings,
+static struct omap_nand_platform_data omap_nand_data = {
+   .gpmc_t = nand_default_timings,
 };
 
-void
-__init board_nand_init(struct mtd_partition *nand_parts,
-   u8 nr_parts, u8 cs, int nand_type)
+struct omap_nand_platform_data *
+__init omap_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
+   int nand_type, struct gpmc_timings *gpmc_t)
 {
-   board_nand_data.cs  = cs;
-   board_nand_data.parts   = nand_parts;
-   board_nand_data.nr_parts= nr_parts;
-   board_nand_data.devsize = nand_type;
-
-   board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
-   board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs;
-   gpmc_nand_init(board_nand_data);
+   omap_nand_data.cs   = cs;
+   omap_nand_data.parts= nand_parts;
+   omap_nand_data.nr_parts = nr_parts;
+   omap_nand_data.devsize  = nand_type;
+   omap_nand_data.gpmc_t   = gpmc_t;
+
+   return omap_nand_data;
 }
 #endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */
 
@@ -242,6 +242,7 @@ void __init board_flash_init(struct flash_partitions 
partition_info[],
if (nandcs  GPMC_CS_NUM)
pr_err(NAND: Unable to find configuration in GPMC\n);
else
-   board_nand_init(partition_info[2].parts,
-   partition_info[2].nr_parts, nandcs, nand_type);
+   omap_nand_init(partition_info[2].parts

[PATCH v3 4/9] ARM: OMAP2+: gpmc-nand: populate gpmc configs

2012-04-05 Thread Afzal Mohammed
Currently gpmc is configured in platform for nand.
As configuring gpmc has been moved to gpmc driver,
populate details needed for the driver to configure
gpmc. gpmc driver would configure based on this
information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc-nand.c|   97 ++--
 arch/arm/plat-omap/include/plat/nand.h |8 ++-
 2 files changed, 48 insertions(+), 57 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 386dec8..85de31f 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -21,24 +21,38 @@
 #include plat/board.h
 #include plat/gpmc.h
 
-static struct resource gpmc_nand_resource = {
-   .flags  = IORESOURCE_MEM,
+
+#defineGPMC_NAND_CONFIG_NUM4
+#defineIDX_DEV_SIZE2
+#defineIDX_RDY_BSY 3
+
+static struct gpmc_config gpmc_nand_config[GPMC_NAND_CONFIG_NUM] = {
+   { GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND},
+   { GPMC_CONFIG_WP, 0},
 };
 
-static struct platform_device gpmc_nand_device = {
+static struct gpmc_cs_data gpmc_nand_cs_info = {
+   .config = gpmc_nand_config,
+   .num_config = ARRAY_SIZE(gpmc_nand_config),
+   .irq_flags  = GPMC_IRQ_FIFOEVENT | GPMC_IRQ_TERMINALCOUNT,
+};
+
+static struct gpmc_device_pdata gpmc_nand_info = {
.name   = omap2-nand,
.id = 0,
-   .num_resources  = 1,
-   .resource   = gpmc_nand_resource,
+   .cs_data= gpmc_nand_cs_info,
+   .num_cs = 1,
 };
 
-static int omap2_nand_gpmc_retime(struct omap_nand_platform_data 
*gpmc_nand_data)
-{
-   struct gpmc_timings t;
-   int err;
+static struct gpmc_timings t;
 
-   if (!gpmc_nand_data-gpmc_t)
+static struct gpmc_timings *
+gpmc_nand_retime(struct omap_nand_platform_data *gpmc_nand_data)
+{
+   if (!gpmc_nand_data-gpmc_t) {
+   pr_warn(gpmc timings not provided\n);
return 0;
+   }
 
memset(t, 0, sizeof(t));
t.sync_clk = gpmc_nand_data-gpmc_t-sync_clk;
@@ -68,56 +82,31 @@ static int omap2_nand_gpmc_retime(struct 
omap_nand_platform_data *gpmc_nand_data
t.cs_wr_off = gpmc_round_ns_to_ticks(gpmc_nand_data-gpmc_t-cs_wr_off);
t.wr_cycle  = gpmc_round_ns_to_ticks(gpmc_nand_data-gpmc_t-wr_cycle);
 
-   /* Configure GPMC */
-   if (gpmc_nand_data-devsize == NAND_BUSWIDTH_16)
-   gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_DEV_SIZE, 1);
-   else
-   gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_DEV_SIZE, 0);
-   gpmc_cs_configure(gpmc_nand_data-cs,
-   GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND);
-   err = gpmc_cs_set_timings(gpmc_nand_data-cs, t);
-   if (err)
-   return err;
-
-   return 0;
+   return t;
 }
 
-int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data)
+struct gpmc_device_pdata *
+__init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data)
 {
-   int err = 0;
-   struct device *dev = gpmc_nand_device.dev;
+   gpmc_nand_info.pdata = gpmc_nand_data;
+   gpmc_nand_info.pdata_size = sizeof(*gpmc_nand_data);
 
-   gpmc_nand_device.dev.platform_data = gpmc_nand_data;
+   gpmc_nand_cs_info.cs = gpmc_nand_data-cs;
+   gpmc_nand_cs_info.mem_size = NAND_IO_SIZE;
 
-   err = gpmc_cs_request(gpmc_nand_data-cs, NAND_IO_SIZE,
-   gpmc_nand_data-phys_base);
-   if (err  0) {
-   dev_err(dev, Cannot request GPMC CS\n);
-   return err;
-   }
+   gpmc_nand_cs_info.timing = gpmc_nand_retime(gpmc_nand_data);
 
-/* Set timings in GPMC */
-   err = omap2_nand_gpmc_retime(gpmc_nand_data);
-   if (err  0) {
-   dev_err(dev, Unable to set gpmc timings: %d\n, err);
-   return err;
-   }
-
-   /* Enable RD PIN Monitoring Reg */
-   if (gpmc_nand_data-dev_ready) {
-   gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_RDY_BSY, 1);
-   }
-
-   err = platform_device_register(gpmc_nand_device);
-   if (err  0) {
-   dev_err(dev, Unable to register NAND device\n);
-   goto out_free_cs;
-   }
-
-   return 0;
+   gpmc_nand_config[IDX_DEV_SIZE].cmd = GPMC_CONFIG_DEV_SIZE;
+   if (gpmc_nand_data-devsize == NAND_BUSWIDTH_16)
+   gpmc_nand_config[IDX_DEV_SIZE].val = 1;
+   else
+   gpmc_nand_config[IDX_DEV_SIZE].val = 0;
 
-out_free_cs:
-   gpmc_cs_free(gpmc_nand_data-cs);
+   gpmc_nand_config[IDX_RDY_BSY].cmd = GPMC_CONFIG_RDY_BSY;
+   if (gpmc_nand_data-dev_ready)
+   gpmc_nand_config[IDX_RDY_BSY].val = 1;
+   else
+   gpmc_nand_config[IDX_RDY_BSY].val = 0;
 
-   return err;
+   return gpmc_nand_info;
 }
diff --git a/arch/arm/plat-omap/include/plat/nand.h

[PATCH v3 5/9] ARM: OMAP2+: gpmc-smsc911x: gpmc driver information

2012-04-05 Thread Afzal Mohammed
gpmc has been converted to driver. And all gpmc related
configuration would be done by gpmc driver. Provide
gpmc driver with sufficient information so that it can
configure.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc-smsc911x.c |   59 ---
 arch/arm/plat-omap/include/plat/gpmc-smsc911x.h |9 +++-
 2 files changed, 39 insertions(+), 29 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-smsc911x.c 
b/arch/arm/mach-omap2/gpmc-smsc911x.c
index b6c77be..52192a9 100644
--- a/arch/arm/mach-omap2/gpmc-smsc911x.c
+++ b/arch/arm/mach-omap2/gpmc-smsc911x.c
@@ -24,13 +24,8 @@
 #include plat/gpmc.h
 #include plat/gpmc-smsc911x.h
 
-static struct resource gpmc_smsc911x_resources[] = {
-   [0] = {
-   .flags  = IORESOURCE_MEM,
-   },
-   [1] = {
-   .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-   },
+static struct resource gpmc_smsc911x_resources = {
+   .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
 };
 
 static struct smsc911x_platform_config gpmc_smsc911x_config = {
@@ -44,26 +39,42 @@ static struct smsc911x_platform_config gpmc_smsc911x_config 
= {
  * assume that pin multiplexing is done in the board-*.c file,
  * or in the bootloader.
  */
-void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *gpmc_cfg)
+__init struct gpmc_device_pdata *
+gpmc_smsc911x_init(struct omap_smsc911x_platform_data *gpmc_cfg)
 {
-   struct platform_device *pdev;
-   unsigned long cs_mem_base;
int ret;
+   struct gpmc_device_pdata *gpmc_pdev;
+   struct gpmc_cs_data *gpmc_cs;
 
-   if (gpmc_cs_request(gpmc_cfg-cs, SZ_16M, cs_mem_base)  0) {
-   pr_err(Failed to request GPMC mem region\n);
-   return;
+   gpmc_pdev = kzalloc(sizeof(*gpmc_pdev), GFP_KERNEL);
+   if (gpmc_pdev == NULL)
+   return gpmc_pdev;
+
+   gpmc_cs = kzalloc(sizeof(*gpmc_cs), GFP_KERNEL);
+   if (gpmc_pdev == NULL) {
+   kfree(gpmc_pdev);
+   return NULL;
}
 
-   gpmc_smsc911x_resources[0].start = cs_mem_base + 0x0;
-   gpmc_smsc911x_resources[0].end = cs_mem_base + 0xff;
+   gpmc_pdev-cs_data = gpmc_cs;
+   gpmc_pdev-num_cs = 1;
+   gpmc_pdev-name = smsc911x;
+   gpmc_pdev-id = gpmc_cfg-id;
+   gpmc_pdev-pdata = gpmc_smsc911x_config;
+   gpmc_pdev-pdata_size = sizeof(gpmc_smsc911x_config);
+
+   gpmc_cs-cs = gpmc_cfg-cs;
+   gpmc_cs-mem_size = 0xff;
+
+   gpmc_pdev-per_res = gpmc_smsc911x_resources;
+   gpmc_pdev-num_per_res = 1;
 
if (gpio_request_one(gpmc_cfg-gpio_irq, GPIOF_IN, smsc911x irq)) {
pr_err(Failed to request IRQ GPIO%d\n, gpmc_cfg-gpio_irq);
goto free1;
}
 
-   gpmc_smsc911x_resources[1].start = gpio_to_irq(gpmc_cfg-gpio_irq);
+   gpmc_smsc911x_resources.start = gpio_to_irq(gpmc_cfg-gpio_irq);
 
if (gpio_is_valid(gpmc_cfg-gpio_reset)) {
ret = gpio_request_one(gpmc_cfg-gpio_reset,
@@ -81,21 +92,15 @@ void __init gpmc_smsc911x_init(struct 
omap_smsc911x_platform_data *gpmc_cfg)
 
gpmc_smsc911x_config.flags = gpmc_cfg-flags ? : SMSC911X_USE_16BIT;
 
-   pdev = platform_device_register_resndata(NULL, smsc911x, gpmc_cfg-id,
-gpmc_smsc911x_resources, ARRAY_SIZE(gpmc_smsc911x_resources),
-gpmc_smsc911x_config, sizeof(gpmc_smsc911x_config));
-   if (!pdev) {
-   pr_err(Unable to register platform device\n);
-   gpio_free(gpmc_cfg-gpio_reset);
-   goto free2;
-   }
-
-   return;
+   return gpmc_pdev;
 
 free2:
gpio_free(gpmc_cfg-gpio_irq);
 free1:
-   gpmc_cs_free(gpmc_cfg-cs);
+   kfree(gpmc_cs);
+   kfree(gpmc_pdev);
 
pr_err(Could not initialize smsc911x device\n);
+
+   return NULL;
 }
diff --git a/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h 
b/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h
index ea6c9c8..66dc7f1 100644
--- a/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h
+++ b/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h
@@ -11,6 +11,8 @@
  * published by the Free Software Foundation.
  */
 
+#includeplat/gpmc.h
+
 #ifndef __ASM_ARCH_OMAP_GPMC_SMSC911X_H__
 
 struct omap_smsc911x_platform_data {
@@ -23,12 +25,15 @@ struct omap_smsc911x_platform_data {
 
 #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
 
-extern void gpmc_smsc911x_init(struct omap_smsc911x_platform_data *d);
+extern struct gpmc_device_pdata *
+gpmc_smsc911x_init(struct omap_smsc911x_platform_data *d);
 
 #else
 
-static inline void gpmc_smsc911x_init(struct omap_smsc911x_platform_data *d)
+static inline struct gpmc_device_pdata *
+gpmc_smsc911x_init(struct omap_smsc911x_platform_data *d)
 {
+   return NULL;
 }
 
 #endif
-- 
1.7.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord

[PATCH v3 6/9] mtd: nand: omap2: obtain memory from resource

2012-04-05 Thread Afzal Mohammed
gpmc being converted to driver, provides drivers
of peripheral connected memory space used by the
peripheral as memory resource.

Modify nand omap driver to obtain memory detials
from resource structure.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/plat-omap/include/plat/nand.h |1 -
 drivers/mtd/nand/omap2.c   |   20 ++--
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/nand.h 
b/arch/arm/plat-omap/include/plat/nand.h
index 30c61c9..570c4f4 100644
--- a/arch/arm/plat-omap/include/plat/nand.h
+++ b/arch/arm/plat-omap/include/plat/nand.h
@@ -26,7 +26,6 @@ struct omap_nand_platform_data {
booldev_ready;
int gpmc_irq;
enum nand_ioxfer_type;
-   unsigned long   phys_base;
int devsize;
enum omap_ecc   ecc_opt;
struct gpmc_nand_regs   reg;
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index c2b0bba..be4b321 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -118,6 +118,7 @@ struct omap_nand_info {
 
int gpmc_cs;
unsigned long   phys_base;
+   unsigned long   mem_size;
struct completion   comp;
int dma_ch;
int gpmc_irq;
@@ -931,6 +932,7 @@ static int __devinit omap_nand_probe(struct platform_device 
*pdev)
struct omap_nand_platform_data  *pdata;
int err;
int i, offset;
+   struct resource *res;
 
pdata = pdev-dev.platform_data;
if (pdata == NULL) {
@@ -950,7 +952,6 @@ static int __devinit omap_nand_probe(struct platform_device 
*pdev)
info-pdev = pdev;
 
info-gpmc_cs   = pdata-cs;
-   info-phys_base = pdata-phys_base;
 
info-mtd.priv  = info-nand;
info-mtd.name  = dev_name(pdev-dev);
@@ -959,16 +960,23 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
info-nand.options  = pdata-devsize;
info-nand.options  |= NAND_SKIP_BBTSCAN;
 
-   /* NAND write protect off */
-   gpmc_cs_configure(info-gpmc_cs, GPMC_CONFIG_WP, 0);
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   if (res == NULL) {
+   err = -EINVAL;
+   dev_err(pdev-dev, error getting memory resource\n);
+   goto out_free_info;
+   }
+
+   info-phys_base = res-start;
+   info-mem_size = resource_size(res);
 
-   if (!request_mem_region(info-phys_base, NAND_IO_SIZE,
+   if (!request_mem_region(info-phys_base, info-mem_size,
pdev-dev.driver-name)) {
err = -EBUSY;
goto out_free_info;
}
 
-   info-nand.IO_ADDR_R = ioremap(info-phys_base, NAND_IO_SIZE);
+   info-nand.IO_ADDR_R = ioremap(info-phys_base, info-mem_size);
if (!info-nand.IO_ADDR_R) {
err = -ENOMEM;
goto out_release_mem_region;
@@ -1110,7 +1118,7 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
return 0;
 
 out_release_mem_region:
-   release_mem_region(info-phys_base, NAND_IO_SIZE);
+   release_mem_region(info-phys_base, info-mem_size);
 out_free_info:
kfree(info);
 
-- 
1.7.9.3

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


[PATCH v3 7/9] mtd: nand: omap2: use gpmc provided irqs

2012-04-05 Thread Afzal Mohammed
GPMC driver provides it's clientsd with interrupts that can be used
through struct resource. Make use of it for irq mode functionality.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 drivers/mtd/nand/omap2.c |   67 +-
 1 file changed, 42 insertions(+), 25 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index be4b321..440536b 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -121,7 +121,8 @@ struct omap_nand_info {
unsigned long   mem_size;
struct completion   comp;
int dma_ch;
-   int gpmc_irq;
+   int gpmc_irq_fifo;
+   int gpmc_irq_count;
enum {
OMAP_NAND_IO_READ = 0,  /* read */
OMAP_NAND_IO_WRITE, /* write */
@@ -472,13 +473,11 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev)
 {
struct omap_nand_info *info = (struct omap_nand_info *) dev;
u32 bytes;
-   u32 irq_stat;
 
-   irq_stat = gpmc_read_status(GPMC_GET_IRQ_STATUS);
bytes = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT);
bytes = bytes   0xFFFC; /* io in multiple of 4 bytes */
if (info-iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */
-   if (irq_stat  0x2)
+   if (this_irq == info-gpmc_irq_count)
goto done;
 
if (info-buf_len  (info-buf_len  bytes))
@@ -495,20 +494,17 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev)
(u32 *)info-buf, bytes  2);
info-buf = info-buf + bytes;
 
-   if (irq_stat  0x2)
+   if (this_irq == info-gpmc_irq_count)
goto done;
}
-   gpmc_cs_configure(info-gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat);
 
return IRQ_HANDLED;
 
 done:
complete(info-comp);
-   /* disable irq */
-   gpmc_cs_configure(info-gpmc_cs, GPMC_ENABLE_IRQ, 0);
 
-   /* clear status */
-   gpmc_cs_configure(info-gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat);
+   disable_irq_nosync(info-gpmc_irq_fifo);
+   disable_irq_nosync(info-gpmc_irq_count);
 
return IRQ_HANDLED;
 }
@@ -542,9 +538,9 @@ static void omap_read_buf_irq_pref(struct mtd_info *mtd, 
u_char *buf, int len)
goto out_copy;
 
info-buf_len = len;
-   /* enable irq */
-   gpmc_cs_configure(info-gpmc_cs, GPMC_ENABLE_IRQ,
-   (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT));
+
+   enable_irq(info-gpmc_irq_count);
+   enable_irq(info-gpmc_irq_fifo);
 
/* waiting for read to complete */
wait_for_completion(info-comp);
@@ -591,12 +587,13 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd,
goto out_copy;
 
info-buf_len = len;
-   /* enable irq */
-   gpmc_cs_configure(info-gpmc_cs, GPMC_ENABLE_IRQ,
-   (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT));
+
+   enable_irq(info-gpmc_irq_count);
+   enable_irq(info-gpmc_irq_fifo);
 
/* waiting for write to complete */
wait_for_completion(info-comp);
+
/* wait for data to flushed-out before reset the prefetch */
tim = 0;
limit = (loops_per_jiffy *  msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS));
@@ -982,6 +979,14 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
goto out_release_mem_region;
}
 
+   info-gpmc_irq_fifo = platform_get_irq(pdev, 0);
+   if (info-gpmc_irq_fifo == -ENXIO)
+   dev_warn(pdev-dev, error getting FIFO IRQ\n);
+
+   info-gpmc_irq_count = platform_get_irq(pdev, 1);
+   if (info-gpmc_irq_fifo == -ENXIO)
+   dev_warn(pdev-dev, error getting TERMINALCOUNT IRQ\n);
+
info-nand.controller = info-controller;
 
info-nand.IO_ADDR_W = info-nand.IO_ADDR_R;
@@ -1037,17 +1042,24 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
break;
 
case NAND_OMAP_PREFETCH_IRQ:
-   err = request_irq(pdata-gpmc_irq,
-   omap_nand_irq, IRQF_SHARED, gpmc-nand, info);
+   err = request_irq(info-gpmc_irq_fifo,  omap_nand_irq,
+   IRQF_SHARED, gpmc-nand-fifo, info);
if (err) {
dev_err(pdev-dev, requesting irq(%d) error:%d,
-   pdata-gpmc_irq, err);
+   info-gpmc_irq_fifo, err);
goto out_release_mem_region;
-   } else {
-   info-gpmc_irq   = pdata-gpmc_irq;
-   info-nand.read_buf  = omap_read_buf_irq_pref;
-   info-nand.write_buf

[PATCH v3 8/9] mtd: nand: omap2: handle nand on gpmc

2012-04-05 Thread Afzal Mohammed
GPMC driver has been modified to fill NAND platform data with GPMC
NAND register details. As these registers are accessible in NAND
driver itself, configure NAND in GPMC by itself.

Note: Verfying that other CS have not yet enabled for prefetch  ecc
has to be incorporated. Currently this causes no issues as there are
no boards that use NAND on multiple CS. With GPMC modifications,
perhaps it would be better to consider NAND connected on multiple CS
as a single peripheral using multiple CS. This would make handling
multiple CS issues easier.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 drivers/mtd/nand/omap2.c |  209 --
 1 file changed, 165 insertions(+), 44 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 440536b..34fb726 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -129,8 +129,79 @@ struct omap_nand_info {
} iomode;
u_char  *buf;
int buf_len;
+   struct gpmc_nand_regs   reg;
 };
 
+#definePREFETCH_CONFIG1_CS_SHIFT   24
+#defineECC_CONFIG_CS_SHIFT 1
+#defineCS_MASK 0x7
+#defineENABLE_PREFETCH (0x1  7)
+#defineDMA_MPU_MODE_SHIFT  2
+#defineECCSIZE1_SHIFT  22
+#defineECC1RESULTSIZE  0x1
+#defineECC_CLEAR_SHIFT 8
+#defineECC10x1
+
+/**
+ * omap_prefetch_enable - configures and starts prefetch transfer
+ * @cs: cs (chip select) number
+ * @fifo_th: fifo threshold to be used for read/ write
+ * @dma_mode: dma mode enable (1) or disable (0)
+ * @u32_count: number of bytes to be transferred
+ * @is_write: prefetch read(0) or write post(1) mode
+ */
+static int omap_prefetch_enable(int cs, int fifo_th, int dma_mode,
+   unsigned int u32_count, int is_write, struct omap_nand_info *info)
+{
+   u32 val;
+
+   if (fifo_th  PREFETCH_FIFOTHRESHOLD_MAX) {
+   pr_err(gpmc: fifo threshold is not supported\n);
+   return -1;
+   } else if (!(readl(info-reg.gpmc_prefetch_control))) {
+   /* Set the amount of bytes to be prefetched */
+   writel(u32_count, info-reg.gpmc_prefetch_config2);
+
+   /* Set dma/mpu mode, the prefetch read / post write and
+* enable the engine. Set which cs is has requested for.
+*/
+   val = ((cs  PREFETCH_CONFIG1_CS_SHIFT) |
+   PREFETCH_FIFOTHRESHOLD(fifo_th) |
+   ENABLE_PREFETCH |
+   (dma_mode  DMA_MPU_MODE_SHIFT) |
+   (0x1  is_write));
+   writel(val, info-reg.gpmc_prefetch_config1);
+
+   /*  Start the prefetch engine */
+   writel(0x1, info-reg.gpmc_prefetch_control);
+   } else {
+   return -EBUSY;
+   }
+
+   return 0;
+}
+
+/**
+ * omap_prefetch_reset - disables and stops the prefetch engine
+ */
+static int omap_prefetch_reset(int cs, struct omap_nand_info *info)
+{
+   u32 config1;
+
+   /* check if the same module/cs is trying to reset */
+   config1 = readl(info-reg.gpmc_prefetch_config1);
+   if (((config1  PREFETCH_CONFIG1_CS_SHIFT)  CS_MASK) != cs)
+   return -EINVAL;
+
+   /* Stop the PFPW engine */
+   writel(0x0, info-reg.gpmc_prefetch_control);
+
+   /* Reset/disable the PFPW engine */
+   writel(0x0, info-reg.gpmc_prefetch_config1);
+
+   return 0;
+}
+
 /**
  * omap_hwcontrol - hardware specific access to control-lines
  * @mtd: MTD device structure
@@ -149,13 +220,13 @@ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, 
unsigned int ctrl)
 
if (cmd != NAND_CMD_NONE) {
if (ctrl  NAND_CLE)
-   gpmc_nand_write(info-gpmc_cs, GPMC_NAND_COMMAND, cmd);
+   writeb(cmd, info-reg.gpmc_nand_command);
 
else if (ctrl  NAND_ALE)
-   gpmc_nand_write(info-gpmc_cs, GPMC_NAND_ADDRESS, cmd);
+   writeb(cmd, info-reg.gpmc_nand_address);
 
else /* NAND_NCE */
-   gpmc_nand_write(info-gpmc_cs, GPMC_NAND_DATA, cmd);
+   writeb(cmd, info-reg.gpmc_nand_data);
}
 }
 
@@ -189,7 +260,8 @@ static void omap_write_buf8(struct mtd_info *mtd, const 
u_char *buf, int len)
iowrite8(*p++, info-nand.IO_ADDR_W);
/* wait until buffer is available for write */
do {
-   status = gpmc_read_status(GPMC_STATUS_BUFFER);
+   status = readl(info-reg.gpmc_status) 
+   GPMC_STATUS_BUFF_EMPTY;
} while (!status

[TMP] OMAP3EVM: Test gpmc nand smsc911x

2012-04-05 Thread Afzal Mohammed
Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-omap3evm.c |   95 +-
 1 file changed, 94 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/board-omap3evm.c 
b/arch/arm/mach-omap2/board-omap3evm.c
index 49df127..60938af 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -23,6 +23,7 @@
 #include linux/input/matrix_keypad.h
 #include linux/leds.h
 #include linux/interrupt.h
+#include linux/mtd/nand.h
 
 #include linux/spi/spi.h
 #include linux/spi/ads7846.h
@@ -41,6 +42,7 @@
 #include asm/mach/arch.h
 #include asm/mach/map.h
 
+#include plat/nand.h
 #include plat/board.h
 #include plat/usb.h
 #include common.h
@@ -52,6 +54,7 @@
 #include sdram-micron-mt46h32m32lf-6.h
 #include hsmmc.h
 #include common-board-devices.h
+#include board-flash.h
 
 #define OMAP3_EVM_TS_GPIO  175
 #define OMAP3_EVM_EHCI_VBUS22
@@ -102,6 +105,36 @@ static void __init omap3_evm_get_revision(void)
}
 }
 
+static struct gpmc_device_pdata *gpmc_data_array[3];
+static struct gpmc_device_pdata **gpmc_data_cur = gpmc_data_array;
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_data_array,
+};
+
+static struct resource gpmc_resources[] = {
+   {
+   .start = OMAP34XX_GPMC_BASE,
+   .end   = OMAP34XX_GPMC_BASE + SZ_4K - 1,
+   .flags = IORESOURCE_MEM,
+   },
+   {
+   .start = INT_34XX_GPMC_IRQ,
+   .end   = INT_34XX_GPMC_IRQ,
+   .flags = IORESOURCE_IRQ,
+   },
+};
+
+static struct platform_device gpmc_device = {
+   .name   = omap-gpmc,
+   .id = -1,
+   .num_resources  = ARRAY_SIZE(gpmc_resources),
+   .resource   = gpmc_resources,
+   .dev= {
+   .platform_data = gpmc_data,
+   }
+};
+
 #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
 #include plat/gpmc-smsc911x.h
 
@@ -114,6 +147,8 @@ static struct omap_smsc911x_platform_data smsc911x_cfg = {
 
 static inline void __init omap3evm_init_smsc911x(void)
 {
+   struct gpmc_device_pdata *gpmc_smsc911x_info;
+
/* Configure ethernet controller reset gpio */
if (cpu_is_omap3430()) {
if (get_omap3_evm_rev() == OMAP3EVM_BOARD_GEN_1)
@@ -122,7 +157,11 @@ static inline void __init omap3evm_init_smsc911x(void)
smsc911x_cfg.gpio_reset = OMAP3EVM_GEN2_ETHR_GPIO_RST;
}
 
-   gpmc_smsc911x_init(smsc911x_cfg);
+   gpmc_smsc911x_info = gpmc_smsc911x_init(smsc911x_cfg);
+   if (gpmc_smsc911x_info)
+   *gpmc_data_cur++ = gpmc_smsc911x_info;
+   else
+   pr_err(error: unable to initilaize gpmc smsc911x\n);
 }
 
 #else
@@ -523,6 +562,41 @@ static struct usbhs_omap_board_data usbhs_bdata __initdata 
= {
.reset_gpio_port[2]  = -EINVAL
 };
 
+/*
+ * NAND
+ */
+static struct mtd_partition omap3_evm_nand_partitions[] = {
+   /* All the partition sizes are listed in terms of NAND block size */
+   {
+   .name   = X-Loader-NAND,
+   .offset = 0,
+   .size   = 4 * (64 * 2048),
+   .mask_flags = MTD_WRITEABLE,/* force read-only */
+   },
+   {
+   .name   = U-Boot-NAND,
+   .offset = MTDPART_OFS_APPEND,   /* Offset = 0x8 */
+   .size   = 10 * (64 * 2048),
+   .mask_flags = MTD_WRITEABLE,/* force read-only */
+   },
+   {
+   .name   = Boot Env-NAND,
+
+   .offset = MTDPART_OFS_APPEND,   /* Offset = 0x1c */
+   .size   = 6 * (64 * 2048),
+   },
+   {
+   .name   = Kernel-NAND,
+   .offset = MTDPART_OFS_APPEND,   /* Offset = 0x28 */
+   .size   = 40 * (64 * 2048),
+   },
+   {
+   .name   = File System - NAND,
+   .size   = MTDPART_SIZ_FULL,
+   .offset = MTDPART_OFS_APPEND,   /* Offset = 0x78 */
+   },
+};
+
 #ifdef CONFIG_OMAP_MUX
 static struct omap_board_mux omap35x_board_mux[] __initdata = {
OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP |
@@ -630,6 +704,8 @@ static struct regulator_consumer_supply dummy_supplies[] = {
 
 static void __init omap3_evm_init(void)
 {
+   struct omap_nand_platform_data *nand_data;
+
omap3_evm_get_revision();
regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
 
@@ -681,6 +757,23 @@ static void __init omap3_evm_init(void)
omap3evm_init_smsc911x();
omap3_evm_display_init();
omap3_evm_wl12xx_init();
+   /* NAND */
+   nand_data = omap_nand_init(omap3_evm_nand_partitions,
+   ARRAY_SIZE(omap3_evm_nand_partitions),
+   0

[PATCH 00/39] OMAP GPMC driver conversion

2012-05-01 Thread Afzal Mohammed
Hi,

GPMC driver conversion patch series. Some peripherals has GPMC helper
functions, these has been modified to cater to the needs of GPMC
driver. All the boards using GPMC has been adapted to use the new
GPMC driver.

GPMC HWMOD entry for OMAP2/3 has been added. On OMAP3, kernel does
spit omap_hwmod: gpmc: cannot be enabled for reset (3), but
peripherals connected via GPMC are working. Really shaky about OMAP2
GPMC HWMOD entry. Would be helpful if someone can help me in resolving
warning on OMAP3  verify whether OMAP2 entry is proper. The series
adapts to HWMOD.

Drivers, NAND  OneNAND of OMAP has been modified to make use of GPMC
changes  cleaned up the now unnecessary exported symbol usages.

This series has been made on top of,
5e136da Linux-omap rebuilt: Updated to -rc5,
A patch by Javier Martinez Canillas jav...@dowhile0.org,
OMAP3: igep0020: Add support for Micron NAND Flash storage memory,
has also been incorporated into the series as this was necessary for
igep0020 board.

This has been tested on omap3 evm (SMSC911x)  beagle board (NAND)

I would need help to get these changes tested on other boards using
GPMC. Expected problematic boards are those having OMAP2xxx SoCs,
apollon board. In the case of apollon, in addition to it being
OMAP2xxx, it was modified to use gpmc_smc91x_init instead of directly
writing to configuration registers.

Additional features that currently boards in mainline does not make
use of like, waitpin interrupt handling, changes to leverage revision
6 IP differences has not been incorporated.

GPMC driver now provides NAND driver with GPMC-NAND registers so that
OMAP NAND driver can handle those by itself instead of using exported
symbols.

Acquiring CS for NAND has also been incorporated, it has been made as
a separate patch as it is felt that this should probably go away,
explained in the relevant patch.

GPMC (General Purpose Memory Controller) in brief:
GPMC is an unified memory controller dedicated to interfacing external
memory devices like
 Asynchronous SRAM like memories and application specific integrated circuit 
devices.
 Asynchronous, synchronous, and page mode burst NOR flash devices NAND flash
 Pseudo-SRAM devices

GPMC details can be referred in AM335X Technical Reference Manual
@ http://www.ti.com/lit/pdf/spruh73

v4: Handle wait pin (except for interrupts), enhance configuration
 timing interface of GPMC to take care of all boards. Dynamic
allocation of interrupt instead of static. Convert remaining
peripherals to work with GPMC driver. Handle acquiring NAND CS#,
adapt to HWMOD, update HWMOD OMAP2/3 entries, other minor
commenst on v3.
v3: Single device structure passed from platform for peripherals using
multiple CS instead of using multiple device structure having a few
redundant data, handle interrupts, GPMC NAND handling by GPMC NAND
driver instead of GPMC driver
v2: Avoid code movement that kept similar code together (for easy review)

TODO: Cleanup

Regards
Afzal

Afzal Mohammed (38):
  ARM: OMAP2+: gpmc: driver conversion
  ARM: OMAP2+: gpmc: Adapt to HWMOD
  ARM: OMAP2+: gpmc: register details for nand driver
  ARM: OMAP2+: gpmc: Acquire NAND CS value
  ARM: OMAP2+: nand: create platform data structure
  ARM: OMAP2+: onenand: return value in init function
  ARM: OMAP2+: gpmc-nand: Adapt to use gpmc driver
  ARM: OMAP2+: gpmc-onenand: Adapt to use gpmc driver
  ARM: OMAP2+: flash: Adapt to gpmc driver
  ARM: OMAP2+: gpmc-smsc911x: Adapt to use gpmc driver
  ARM: OMAP2+: gpmc-smc91x: Adapt to use gpmc driver
  ARM: OMAP2+: gpmc-tusb6010: Adapt to gpmc driver
  ARM: OMAP3: hwmod data: add gpmc
  ARM: OMAP2xxx: hwmod data: add gpmc
  mtd: nand: omap2: obtain memory from resource
  mtd: nand: omap2: use gpmc provided irqs
  mtd: nand: omap2: handle nand on gpmc
  mtd: onenand: omap: obtain memory from resource
  ARM: OMAP2+: board omap3evm: gpmc driver adaptation
  ARM: OMAP2+: board omap3beagle: gpmc driver adaptation
  ARM: OMAP2+: board apollon: gpmc driver adaptation
  ARM: OMAP2+: board h4: gpmc driver adaptation
  ARM: OMAP2+: board 3630sdp: gpmc driver adaptation
  ARM: OMAP2+: board 3430sdp: gpmc driver adaptation
  ARM: OMAP2+: board 2430sdp: gpmc driver adaptation
  ARM: OMAP2+: board cm-t3517: gpmc driver adaptation
  ARM: OMAP2+: board cm-t35: gpmc driver adaptation
  ARM: OMAP2+: board ldp: gpmc driver adaptation
  ARM: OMAP2+: board n8x0: gpmc driver adaptation
  ARM: OMAP2+: board omap3logic: gpmc driver adaptation
  ARM: OMAP2+: board omap3pandora: gpmc driver adaptation
  ARM: OMAP2+: board omap3stalker: gpmc driver adaptation
  ARM: OMAP2+: board omap4pcm049: gpmc driver adaptation
  ARM: OMAP2+: board overo: gpmc driver adaptation
  ARM: OMAP2+: board rm680: gpmc driver adaptation
  ARM: OMAP2+: board rx51: gpmc driver adaptation
  ARM: OMAP2+: board zoom-debugboard: gpmc driver adaptation
  ARM: OMAP2+: board igep0020: gpmc driver adaptation

Javier Martinez Canillas (1):
  OMAP3: igep0020: Add support

[PATCH 02/39] ARM: OMAP2+: gpmc: Adapt to HWMOD

2012-05-01 Thread Afzal Mohammed
Create API for platforms to adapt gpmc to HWMOD

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |   52 +++-
 arch/arm/plat-omap/include/plat/gpmc.h |1 +
 2 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 12916f3..c8d07bb 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -33,6 +33,8 @@
 
 #include plat/sdrc.h
 
+#include plat/omap_device.h
+
 /* GPMC register offsets */
 #define GPMC_REVISION  0x00
 #define GPMC_SYSCONFIG 0x10
@@ -276,6 +278,31 @@ unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
return ticks * gpmc_get_fclk_period() / 1000;
 }
 
+int __init omap_init_gpmc(struct gpmc_pdata *pdata)
+{
+   struct omap_hwmod *oh;
+   struct platform_device *pdev;
+   char *name = omap-gpmc;
+   char *oh_name = gpmc;
+
+   pdata-clk_prd = gpmc_get_fclk_period();
+
+   oh = omap_hwmod_lookup(oh_name);
+   if (!oh) {
+   pr_err(Could not look up %s\n, oh_name);
+   return -ENODEV;
+   }
+
+   pdev = omap_device_build(name, -1, oh, pdata,
+   sizeof(*pdata), NULL, 0, 0);
+   if (IS_ERR(pdev)) {
+   WARN(1, Can't build omap_device for %s:%s.\n,
+   name, oh-name);
+   return PTR_ERR(pdev);
+   }
+
+   return 0;
+}
 #ifdef DEBUG
 static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
   int time, const char *name)
@@ -843,24 +870,19 @@ static __devinit void gpmc_mem_init(void)
 
 static int __init gpmc_init(void)
 {
-   int ret = -EINVAL;
-   char *ck = NULL;
-
-   if (cpu_is_omap24xx()) {
-   ck = core_l3_ck;
-   } else if (cpu_is_omap34xx()) {
-   ck = gpmc_fck;
-   } else if (cpu_is_omap44xx()) {
-   ck = gpmc_ck;
-   }
+   char *oh_name = gpmc;
+   struct omap_hwmod *oh;
 
-   if (WARN_ON(!ck))
-   return ret;
+   oh = omap_hwmod_lookup(oh_name);
+   if (!oh) {
+   pr_err(Could not look up %s\n, oh_name);
+   return -ENODEV;
+   }
 
-   gpmc_l3_clk = clk_get(NULL, ck);
+   gpmc_l3_clk = clk_get(NULL, oh-main_clk);
if (IS_ERR(gpmc_l3_clk)) {
-   printk(KERN_ERR Could not get GPMC clock %s\n, ck);
-   BUG();
+   pr_err(error: clk_get on %s\n, oh-main_clk);
+   return -EINVAL;
}
 
clk_enable(gpmc_l3_clk);
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h 
b/arch/arm/plat-omap/include/plat/gpmc.h
index 2eedd99..c5cf020 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -217,6 +217,7 @@ struct gpmc_pdata {
 };
 
 extern int gpmc_cs_reconfigure(char *name, int id, struct gpmc_cs_data *cs);
+extern int omap_init_gpmc(struct gpmc_pdata *pdata);
 
 extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
 extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps);
-- 
1.7.10

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


[PATCH 01/39] ARM: OMAP2+: gpmc: driver conversion

2012-05-01 Thread Afzal Mohammed
Convert GPMC code to driver. Boards using GPMC should provide driver
with type of configuration, timing, CS. Platform devices would then be
created for each connected peripheral (details also to be passed by
board so that it reaches respective driver). And GPMC driver would
populate memory resource details for the connected peripheral driver.
Boards should inform gpmc driver with platform data destined for
peripheral driver. gpmc driver will provide the same information to
peripheral driver.

A peripheral connected to GPMC can have multiple address spaces using
different chip select. Hence GPMC driver has been provided capability
to create platform device for peripheral using mutiple CS. The
peripheral that made it necessary was tusb6010.

Interrupts of GPMC are presented to drivers of connected peripherals
as resource. A fictitious interrupt controller chip handles these
interrupts at GPMC hardware level. Clients can use normal interrupt
APIs. Platform information of peripheral passed to GPMC driver should
indicate interrupts to be used via flags.

Driver is capable of configuring waitpin, waitpin details has to be
provided per CS. Wait pin has been considered as exclusive resource
as multiple peripherals should not using the same pin, at the same
it is valid for mutiple CS to use same waitpin provided they are
a part of single peripheral (eg. tusb6010)

An exported symbol for reconfiguring GPMC settings has been provided.
OneNAND is the one that neccessitated this.

Acquiring CS# for NAND is done on a few boards. It means, depending
on bootloader to embed this information. Probably CS# being used can
be set in the Kernel, and acquiring it can be removed. If ever this
capbility is needed, GPMC driver has to be made aware of handling it.

Modifications has been made keeping in mind that the driver would
have to move to driver folder. This explains requirement of clk_prd
field; even though clk_prd variable is not necessary as
gpmc_get_fclk_period is present in the same file as of now, this will
help in moving the driver easily to drivers folder.

Code related to GPMC clock may have to continue live in platform
folders as input clock is beyond the control of GPMC and calculating
timing for the peripheral may need other helpers. This explains
presence of 'gpmc_cs_calc_divider' along with 'gpmc_calc_divider',
both doing same work, latter meant to go with driver, former for
calculation in platform code.

Thanks to Vaibhav Hiremath  Jonathan Hunter on their various good
suggestions which resulted in improving the code.

Cc: Vaibhav Hiremath hvaib...@ti.com
Cc: Jon Hunter jon-hun...@ti.com
Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |  877 
 arch/arm/plat-omap/include/plat/gpmc.h |   93 +++-
 2 files changed, 872 insertions(+), 98 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 580e684..12916f3 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -14,8 +14,11 @@
  */
 #undef DEBUG
 
+#include linux/platform_device.h
+
 #include linux/irq.h
 #include linux/kernel.h
+#include linux/slab.h
 #include linux/init.h
 #include linux/err.h
 #include linux/clk.h
@@ -53,6 +56,45 @@
 #define GPMC_CS0_OFFSET0x60
 #define GPMC_CS_SIZE   0x30
 
+/* GPMC register bits */
+#defineGPMC_CONFIG1_TIMEPARAGRANULARITYBIT(4)
+#defineGPMC_CONFIG1_DEVICETYPE_NAND
GPMC_CONFIG1_DEVICETYPE(0x2)
+#defineGPMC_CONFIG1_WAIT_PIN_SEL_MASK  
GPMC_CONFIG1_WAIT_PIN_SEL(0x3)
+#defineGPMC_CONFIG1_WAIT_MON_TIME(val) ((val  0x3)  18)
+#defineGPMC_CONFIG1_WRITEMULTIPLE  BIT(28)
+#defineGPMC_CONFIG1_READMULTIPLE   BIT(30)
+#defineGPMC_CONFIG1_WRAPBURST  BIT(31)
+#defineGPMC_CONFIG_WAITPIN_POLARITY_SHIFT  0x8
+#defineGPMC_CONFIG1_WAITPIN_MONITOR_TIME(val)  ((val  0x3)  18)
+#defineGPMC_CONFIG1_WAITPIN_MONITOR_TIME_1 \
+   GPMC_CONFIG1_WAITPIN_MONITOR_TIME(0x1)
+#defineGPMC_CONFIG1_WAITPIN_MONITOR_TIME_2 \
+   GPMC_CONFIG1_WAITPIN_MONITOR_TIME(0x2)
+#defineGPMC_CONFIG1_CLOCKACTIVATION_TIME(val)  ((val  0x3)  25)
+#defineGPMC_CONFIG1_CLOCKACTIVATION_TIME_1 \
+   GPMC_CONFIG1_CLOCKACTIVATION_TIME(0x1)
+#defineGPMC_CONFIG1_CLOCKACTIVATION_TIME_2 \
+   GPMC_CONFIG1_CLOCKACTIVATION_TIME(0x2)
+
+#defineGPMC_CONFIG2_CSEXTRADELAY   BIT(7)
+
+#defineGPMC_CONFIG3_ADVEXTRADELAY  BIT(7)
+
+#defineGPMC_CONFIG4_OEEXTRADELAY   BIT(7)
+#defineGPMC_CONFIG4_WEEXTRADELAY   BIT(23)
+
+#defineGPMC_CONFIG6_CYCLE2CYCLEDIFFCSENBIT(6)
+#defineGPMC_CONFIG6_CYCLE2CYCLESAMECSENBIT(7)
+
+#define

[PATCH 03/39] ARM: OMAP2+: gpmc: register details for nand driver

2012-05-01 Thread Afzal Mohammed
If peripheral connected is NAND, update NAND drivers platform data
with NAND related register addresses so that NAND driver can handle
GPMC NAND operations by itself

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |   25 +
 arch/arm/plat-omap/include/plat/gpmc.h |   16 
 arch/arm/plat-omap/include/plat/nand.h |1 +
 3 files changed, 42 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index c8d07bb..657ce95 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -30,6 +30,7 @@
 
 #include asm/mach-types.h
 #include plat/gpmc.h
+#include plat/nand.h
 
 #include plat/sdrc.h
 
@@ -891,6 +892,28 @@ static int __init gpmc_init(void)
 }
 postcore_initcall(gpmc_init);
 
+static __devinit void gpmc_update_nand_reg(struct gpmc *gpmc,
+   struct omap_nand_platform_data *nand)
+{
+   int cs = nand-cs;
+
+   nand-reg.gpmc_status = gpmc-io_base + GPMC_STATUS;
+   nand-reg.gpmc_nand_command = gpmc-io_base + GPMC_CS0_OFFSET +
+   GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs;
+   nand-reg.gpmc_nand_address = gpmc-io_base + GPMC_CS0_OFFSET +
+   GPMC_CS_NAND_ADDRESS + GPMC_CS_SIZE * cs;
+   nand-reg.gpmc_nand_data = gpmc-io_base + GPMC_CS0_OFFSET +
+   GPMC_CS_NAND_DATA + GPMC_CS_SIZE * cs;
+   nand-reg.gpmc_prefetch_config1 = gpmc-io_base + GPMC_PREFETCH_CONFIG1;
+   nand-reg.gpmc_prefetch_config2 = gpmc-io_base + GPMC_PREFETCH_CONFIG2;
+   nand-reg.gpmc_prefetch_control = gpmc-io_base + GPMC_PREFETCH_CONTROL;
+   nand-reg.gpmc_prefetch_status = gpmc-io_base + GPMC_PREFETCH_STATUS;
+   nand-reg.gpmc_ecc_config = gpmc-io_base + GPMC_ECC_CONFIG;
+   nand-reg.gpmc_ecc_control = gpmc-io_base + GPMC_ECC_CONTROL;
+   nand-reg.gpmc_ecc_size_config = gpmc-io_base + GPMC_ECC_SIZE_CONFIG;
+   nand-reg.gpmc_ecc1_result = gpmc-io_base + GPMC_ECC1_RESULT;
+}
+
 static inline int gpmc_waitpin_is_reserved(struct gpmc *gpmc, unsigned waitpin)
 {
return gpmc-waitpin_map  (0x1  waitpin);
@@ -1427,6 +1450,8 @@ static __devinit int gpmc_probe(struct platform_device 
*pdev)
 
for (i = 0, gdq = gp-device_pdata, gd = gpmc-device;
(i  gp-num_device)  (*gdq); i++, gdq++) {
+   if ((*gdq)-is_nand)
+   gpmc_update_nand_reg(gpmc, (*gdq)-pdata);
ret = gpmc_setup_device(gpmc, gd, *gdq);
if (IS_ERR_VALUE(ret))
dev_err(gpmc-dev, gpmc setup on %s failed\n,
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h 
b/arch/arm/plat-omap/include/plat/gpmc.h
index c5cf020..976a8f0 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -207,6 +207,7 @@ struct gpmc_device_pdata {
unsignedper_res_cnt;
struct gpmc_cs_data *cs_data;
unsignednum_cs;
+   boolis_nand;
 };
 
 struct gpmc_pdata {
@@ -216,6 +217,21 @@ struct gpmc_pdata {
struct gpmc_device_pdata**device_pdata;
 };
 
+struct gpmc_nand_regs {
+   void __iomem*gpmc_status;
+   void __iomem*gpmc_nand_command;
+   void __iomem*gpmc_nand_address;
+   void __iomem*gpmc_nand_data;
+   void __iomem*gpmc_prefetch_config1;
+   void __iomem*gpmc_prefetch_config2;
+   void __iomem*gpmc_prefetch_control;
+   void __iomem*gpmc_prefetch_status;
+   void __iomem*gpmc_ecc_config;
+   void __iomem*gpmc_ecc_control;
+   void __iomem*gpmc_ecc_size_config;
+   void __iomem*gpmc_ecc1_result;
+};
+
 extern int gpmc_cs_reconfigure(char *name, int id, struct gpmc_cs_data *cs);
 extern int omap_init_gpmc(struct gpmc_pdata *pdata);
 
diff --git a/arch/arm/plat-omap/include/plat/nand.h 
b/arch/arm/plat-omap/include/plat/nand.h
index 67fc506..86e4d9c 100644
--- a/arch/arm/plat-omap/include/plat/nand.h
+++ b/arch/arm/plat-omap/include/plat/nand.h
@@ -29,6 +29,7 @@ struct omap_nand_platform_data {
unsigned long   phys_base;
int devsize;
enum omap_ecc   ecc_opt;
+   struct gpmc_nand_regs   reg;
 };
 
 /* minimum size for IO mapping */
-- 
1.7.10

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


[PATCH 04/39] ARM: OMAP2+: gpmc: Acquire NAND CS value

2012-05-01 Thread Afzal Mohammed
Some boards depend on bootloader to update chip select value for NAND.
It is felt that Kernel should not depend on bootloader to get CS, as
for a particular board CS is hardwired and is fixed, hence this can
directly be updated in Kernel. But as CS value for boards that depend
on this behaviour is not available, educate gpmc driver to acquire
chip select value for NAND. this ideally should be removed once CS
for those boards are available.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |   32 +++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 657ce95..ecd3384 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -892,6 +892,30 @@ static int __init gpmc_init(void)
 }
 postcore_initcall(gpmc_init);
 
+static __devinit int gpmc_acquire_nand_cs(struct gpmc *gpmc,
+   struct gpmc_device_pdata *gdp)
+{
+   int cs = 0;
+   struct omap_nand_platform_data *nand = gdp-pdata;
+
+   if ((nand-cs = 0)  (nand-cs  GPMC_CS_NUM))
+   return 0;
+
+   while (cs  GPMC_CS_NUM) {
+   u32 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+   if ((l  GPMC_CONFIG1_DEVICETYPE(~0)) ==
+   GPMC_CONFIG1_DEVICETYPE_NAND) {
+   dev_info(gpmc-dev, found NAND on CS: %d\n, cs);
+   nand-cs = cs;
+   gdp-cs_data-cs = cs;
+   return 0;
+   }
+   cs++;
+   }
+   return -ENODEV;
+}
+
 static __devinit void gpmc_update_nand_reg(struct gpmc *gpmc,
struct omap_nand_platform_data *nand)
 {
@@ -1450,8 +1474,14 @@ static __devinit int gpmc_probe(struct platform_device 
*pdev)
 
for (i = 0, gdq = gp-device_pdata, gd = gpmc-device;
(i  gp-num_device)  (*gdq); i++, gdq++) {
-   if ((*gdq)-is_nand)
+   if ((*gdq)-is_nand) {
+   ret = gpmc_acquire_nand_cs(gpmc, *gdq);
+   if (IS_ERR_VALUE(ret)) {
+   dev_err(gpmc-dev, CS error: %d\n, ret);
+   continue;
+   }
gpmc_update_nand_reg(gpmc, (*gdq)-pdata);
+   }
ret = gpmc_setup_device(gpmc, gd, *gdq);
if (IS_ERR_VALUE(ret))
dev_err(gpmc-dev, gpmc setup on %s failed\n,
-- 
1.7.10

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


[PATCH 05/39] ARM: OMAP2+: nand: create platform data structure

2012-05-01 Thread Afzal Mohammed
New API for updating nand platform data. This has
been created by unifying the two existing ones and
taking out gpmc hardware handling.

From now on, platforms can call omap_nand_init to
initialize platform nand structures, it's fields.
Or can statically create the same.

Acquiring gpmc CS for has been removed. Acquiring CS
is done in GPMC driver. To leverage this feature,
pass CS # as any value outside the allowed range of
0 - 7 (this is valid only for connected NAND),
eg. GPMC_CS_NUM (8)

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-devkit8000.c |6 ++-
 arch/arm/mach-omap2/board-flash.c  |   61 ++--
 arch/arm/mach-omap2/board-flash.h  |   13 --
 arch/arm/mach-omap2/board-ldp.c|4 +-
 arch/arm/mach-omap2/board-omap3beagle.c|6 ++-
 arch/arm/mach-omap2/board-omap3touchbook.c |6 ++-
 arch/arm/mach-omap2/board-overo.c  |5 ++-
 arch/arm/mach-omap2/board-zoom.c   |5 ++-
 arch/arm/mach-omap2/common-board-devices.c |   46 -
 arch/arm/mach-omap2/common-board-devices.h |1 -
 10 files changed, 60 insertions(+), 93 deletions(-)

diff --git a/arch/arm/mach-omap2/board-devkit8000.c 
b/arch/arm/mach-omap2/board-devkit8000.c
index a2010f0..aa352d1 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -59,6 +59,7 @@
 
 #include mux.h
 #include hsmmc.h
+#include board-flash.h
 #include common-board-devices.h
 
 #define OMAP_DM9000_GPIO_IRQ   25
@@ -648,8 +649,9 @@ static void __init devkit8000_init(void)
 
usb_musb_init(NULL);
usbhs_init(usbhs_bdata);
-   omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions,
-ARRAY_SIZE(devkit8000_nand_partitions));
+   board_nand_init(devkit8000_nand_partitions,
+   ARRAY_SIZE(devkit8000_nand_partitions), GPMC_CS_NUM,
+   NAND_BUSWIDTH_16, NULL);
 
/* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal(sdrc_cke0, OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-flash.c 
b/arch/arm/mach-omap2/board-flash.c
index 0349fd2..091aaf6 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -108,45 +108,45 @@ __init board_onenand_init(struct mtd_partition 
*nor_parts, u8 nr_parts, u8 cs)
defined(CONFIG_MTD_NAND_OMAP2_MODULE)
 
 /* Note that all values in this struct are in nanoseconds */
-static struct gpmc_timings nand_timings = {
+struct gpmc_timings nand_default_timings[1] = {
+   {
+   .sync_clk = 0,
 
-   .sync_clk = 0,
+   .cs_on = 0,
+   .cs_rd_off = 36,
+   .cs_wr_off = 36,
 
-   .cs_on = 0,
-   .cs_rd_off = 36,
-   .cs_wr_off = 36,
+   .adv_on = 6,
+   .adv_rd_off = 24,
+   .adv_wr_off = 36,
 
-   .adv_on = 6,
-   .adv_rd_off = 24,
-   .adv_wr_off = 36,
+   .we_off = 30,
+   .oe_off = 48,
 
-   .we_off = 30,
-   .oe_off = 48,
+   .access = 54,
+   .rd_cycle = 72,
+   .wr_cycle = 72,
 
-   .access = 54,
-   .rd_cycle = 72,
-   .wr_cycle = 72,
-
-   .wr_access = 30,
-   .wr_data_mux_bus = 0,
+   .wr_access = 30,
+   .wr_data_mux_bus = 0,
+   },
 };
 
-static struct omap_nand_platform_data board_nand_data = {
-   .gpmc_t = nand_timings,
+static struct omap_nand_platform_data omap_nand_data = {
+   .gpmc_t = nand_default_timings,
 };
 
-void
-__init board_nand_init(struct mtd_partition *nand_parts,
-   u8 nr_parts, u8 cs, int nand_type)
+struct omap_nand_platform_data *
+__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
+   int nand_type, struct gpmc_timings *gpmc_t)
 {
-   board_nand_data.cs  = cs;
-   board_nand_data.parts   = nand_parts;
-   board_nand_data.nr_parts= nr_parts;
-   board_nand_data.devsize = nand_type;
-
-   board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
-   board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs;
-   gpmc_nand_init(board_nand_data);
+   omap_nand_data.cs   = cs;
+   omap_nand_data.parts= nand_parts;
+   omap_nand_data.nr_parts = nr_parts;
+   omap_nand_data.devsize  = nand_type;
+   omap_nand_data.gpmc_t   = gpmc_t;
+
+   return omap_nand_data;
 }
 #endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */
 
@@ -243,5 +243,6 @@ void __init board_flash_init(struct flash_partitions 
partition_info[],
pr_err(NAND: Unable to find configuration in GPMC\n);
else
board_nand_init(partition_info[2].parts,
-   partition_info[2].nr_parts, nandcs, nand_type

[PATCH 06/39] ARM: OMAP2+: onenand: return value in init function

2012-05-01 Thread Afzal Mohammed
Modify board_onenand_init to return platform data. This
would be required for boards to be able to pass it to
gpmc driver so that it finally reaches onenand driver.

Also un-static the function so that boards can use it.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-flash.c |   14 --
 arch/arm/mach-omap2/board-flash.h |   12 
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-omap2/board-flash.c 
b/arch/arm/mach-omap2/board-flash.c
index 091aaf6..8727c05 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -87,22 +87,16 @@ static struct omap_onenand_platform_data board_onenand_data 
= {
.dma_channel= -1,   /* disable DMA in OMAP OneNAND driver */
 };
 
-static void
-__init board_onenand_init(struct mtd_partition *onenand_parts,
-   u8 nr_parts, u8 cs)
+struct omap_onenand_platform_data * __init
+board_onenand_init(struct mtd_partition *onenand_parts, u8 nr_parts, u8 cs)
 {
board_onenand_data.cs   = cs;
board_onenand_data.parts= onenand_parts;
board_onenand_data.nr_parts = nr_parts;
 
-   gpmc_onenand_init(board_onenand_data);
-}
-#else
-static void
-__init board_onenand_init(struct mtd_partition *nor_parts, u8 nr_parts, u8 cs)
-{
+   return board_onenand_data;
 }
-#endif /* CONFIG_MTD_ONENAND_OMAP2 || CONFIG_MTD_ONENAND_OMAP2_MODULE */
+#endif
 
 #if defined(CONFIG_MTD_NAND_OMAP2) || \
defined(CONFIG_MTD_NAND_OMAP2_MODULE)
diff --git a/arch/arm/mach-omap2/board-flash.h 
b/arch/arm/mach-omap2/board-flash.h
index 052964c..75ba49f 100644
--- a/arch/arm/mach-omap2/board-flash.h
+++ b/arch/arm/mach-omap2/board-flash.h
@@ -52,3 +52,15 @@ board_nand_init(struct mtd_partition *nand_parts,
return NULL;
 }
 #endif
+
+#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+   defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+extern struct omap_onenand_platform_data * __init
+board_onenand_init(struct mtd_partition *onenand_parts, u8 nr_parts, u8 cs);
+#else
+static inline struct omap_onenand_platform_data *
+__init board_onenand_init(struct mtd_partition *nor_parts, u8 nr_parts, u8 cs)
+{
+   return NULL;
+}
+#endif
-- 
1.7.10

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


[PATCH 07/39] ARM: OMAP2+: gpmc-nand: Adapt to use gpmc driver

2012-05-01 Thread Afzal Mohammed
Currently gpmc is configured in platform for nand.
As configuring gpmc has been moved to gpmc driver,
populate details needed for the driver to configure
gpmc. gpmc driver would configure based on this
information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc-nand.c|   84 
 arch/arm/plat-omap/include/plat/nand.h |8 +--
 2 files changed, 35 insertions(+), 57 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 386dec8..190cdc1 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -21,24 +21,30 @@
 #include plat/board.h
 #include plat/gpmc.h
 
-static struct resource gpmc_nand_resource = {
-   .flags  = IORESOURCE_MEM,
+
+static struct gpmc_cs_data gpmc_nand_cs_info = {
+   .have_config= true,
+   .config = GPMC_DEVICETYPE_NAND,
+   .irq_config = GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT,
 };
 
-static struct platform_device gpmc_nand_device = {
+static struct gpmc_device_pdata gpmc_nand_info = {
.name   = omap2-nand,
.id = 0,
-   .num_resources  = 1,
-   .resource   = gpmc_nand_resource,
+   .cs_data= gpmc_nand_cs_info,
+   .num_cs = 1,
+   .is_nand= true,
 };
 
-static int omap2_nand_gpmc_retime(struct omap_nand_platform_data 
*gpmc_nand_data)
-{
-   struct gpmc_timings t;
-   int err;
+static struct gpmc_timings t;
 
-   if (!gpmc_nand_data-gpmc_t)
+static struct gpmc_timings *
+gpmc_nand_retime(struct omap_nand_platform_data *gpmc_nand_data)
+{
+   if (!gpmc_nand_data-gpmc_t) {
+   pr_warn(gpmc timings not provided\n);
return 0;
+   }
 
memset(t, 0, sizeof(t));
t.sync_clk = gpmc_nand_data-gpmc_t-sync_clk;
@@ -68,56 +74,26 @@ static int omap2_nand_gpmc_retime(struct 
omap_nand_platform_data *gpmc_nand_data
t.cs_wr_off = gpmc_round_ns_to_ticks(gpmc_nand_data-gpmc_t-cs_wr_off);
t.wr_cycle  = gpmc_round_ns_to_ticks(gpmc_nand_data-gpmc_t-wr_cycle);
 
-   /* Configure GPMC */
-   if (gpmc_nand_data-devsize == NAND_BUSWIDTH_16)
-   gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_DEV_SIZE, 1);
-   else
-   gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_DEV_SIZE, 0);
-   gpmc_cs_configure(gpmc_nand_data-cs,
-   GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND);
-   err = gpmc_cs_set_timings(gpmc_nand_data-cs, t);
-   if (err)
-   return err;
-
-   return 0;
+   return t;
 }
 
-int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data)
+struct gpmc_device_pdata *
+__init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data)
 {
-   int err = 0;
-   struct device *dev = gpmc_nand_device.dev;
+   gpmc_nand_info.pdata = gpmc_nand_data;
+   gpmc_nand_info.pdata_size = sizeof(*gpmc_nand_data);
 
-   gpmc_nand_device.dev.platform_data = gpmc_nand_data;
+   gpmc_nand_cs_info.cs = gpmc_nand_data-cs;
+   gpmc_nand_cs_info.mem_size = NAND_IO_SIZE;
 
-   err = gpmc_cs_request(gpmc_nand_data-cs, NAND_IO_SIZE,
-   gpmc_nand_data-phys_base);
-   if (err  0) {
-   dev_err(dev, Cannot request GPMC CS\n);
-   return err;
-   }
+   gpmc_nand_cs_info.timing = gpmc_nand_retime(gpmc_nand_data);
 
-/* Set timings in GPMC */
-   err = omap2_nand_gpmc_retime(gpmc_nand_data);
-   if (err  0) {
-   dev_err(dev, Unable to set gpmc timings: %d\n, err);
-   return err;
-   }
-
-   /* Enable RD PIN Monitoring Reg */
-   if (gpmc_nand_data-dev_ready) {
-   gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_RDY_BSY, 1);
-   }
-
-   err = platform_device_register(gpmc_nand_device);
-   if (err  0) {
-   dev_err(dev, Unable to register NAND device\n);
-   goto out_free_cs;
-   }
-
-   return 0;
+   if (gpmc_nand_data-devsize == NAND_BUSWIDTH_16)
+   gpmc_nand_cs_info.config |= GPMC_DEVICESIZE_16;
 
-out_free_cs:
-   gpmc_cs_free(gpmc_nand_data-cs);
+   if (gpmc_nand_data-dev_ready)
+   gpmc_nand_cs_info.config |= GPMC_WAIT_READ_MON |
+   GPMC_WAIT_WRITE_MON;
 
-   return err;
+   return gpmc_nand_info;
 }
diff --git a/arch/arm/plat-omap/include/plat/nand.h 
b/arch/arm/plat-omap/include/plat/nand.h
index 86e4d9c..30c61c9 100644
--- a/arch/arm/plat-omap/include/plat/nand.h
+++ b/arch/arm/plat-omap/include/plat/nand.h
@@ -36,10 +36,12 @@ struct omap_nand_platform_data {
 #defineNAND_IO_SIZE4
 
 #if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
-extern int gpmc_nand_init(struct omap_nand_platform_data *d);
+extern struct gpmc_device_pdata *
+gpmc_nand_init(struct

[PATCH 08/39] ARM: OMAP2+: gpmc-onenand: Adapt to use gpmc driver

2012-05-01 Thread Afzal Mohammed
Currently gpmc is configured in platform for onenand. As configuring
gpmc has been moved to gpmc driver, populate details needed for the
driver to configure gpmc. gpmc driver would configure based on this
information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc-onenand.c|  111 +++--
 arch/arm/plat-omap/include/plat/onenand.h |7 +-
 2 files changed, 61 insertions(+), 57 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c 
b/arch/arm/mach-omap2/gpmc-onenand.c
index a0fa9bb..d7775d5 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -25,9 +25,17 @@
 
 static struct omap_onenand_platform_data *gpmc_onenand_data;
 
-static struct platform_device gpmc_onenand_device = {
+#define ONENAND_IO_SIZESZ_128K
+
+static struct gpmc_cs_data gpmc_onenand_cs_info = {
+   .mem_size   = ONENAND_IO_SIZE,
+};
+
+static struct gpmc_device_pdata gpmc_onenand_info = {
.name   = omap2-onenand,
.id = -1,
+   .cs_data= gpmc_onenand_cs_info,
+   .num_cs = 1,
 };
 
 static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base)
@@ -79,13 +87,17 @@ static int omap2_onenand_set_async_mode(int cs, void 
__iomem *onenand_base)
t.wr_cycle  = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
 
/* Configure GPMC for asynchronous read */
-   gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
- GPMC_CONFIG1_DEVICESIZE_16 |
- GPMC_CONFIG1_MUXADDDATA);
-
-   err = gpmc_cs_set_timings(cs, t);
-   if (err)
+   gpmc_onenand_cs_info.have_config = true;
+   gpmc_onenand_cs_info.config = GPMC_DEVICESIZE_16 |
+   GPMC_MUXADDDATA |
+   GPMC_DEVICETYPE_NOR;
+   gpmc_onenand_cs_info.timing = t;
+   err = gpmc_cs_reconfigure(gpmc_onenand_info.name,
+   gpmc_onenand_info.id, gpmc_onenand_cs_info);
+   if (err) {
+   pr_err(%s: gpmc_cs_reconfigure failed\n, __func__);
return err;
+   }
 
/* Ensure sync read and sync write are disabled */
reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
@@ -180,7 +192,6 @@ static int omap2_onenand_set_sync_mode(struct 
omap_onenand_platform_data *cfg,
int first_time = 0, hf = 0, vhf = 0, sync_read = 0, sync_write = 0;
int err, ticks_cez;
int cs = cfg-cs, freq = *freq_ptr;
-   u32 reg;
bool clk_dep = false;
 
if (cfg-flags  ONENAND_SYNC_READ) {
@@ -276,27 +287,10 @@ static int omap2_onenand_set_sync_mode(struct 
omap_onenand_platform_data *cfg,
sync_read, sync_write, hf, vhf);
 
if (div == 1) {
-   reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
-   reg |= (1  7);
-   gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
-   reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
-   reg |= (1  7);
-   gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
-   reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
-   reg |= (1  7);
-   reg |= (1  23);
-   gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
-   } else {
-   reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
-   reg = ~(1  7);
-   gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
-   reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
-   reg = ~(1  7);
-   gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
-   reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
-   reg = ~(1  7);
-   reg = ~(1  23);
-   gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
+   t.control.cs_extra_delay = true;
+   t.control.adv_extra_delay = true;
+   t.control.oe_extra_delay = true;
+   t.control.we_extra_delay = true;
}
 
/* Set synchronous read timings */
@@ -348,24 +342,31 @@ static int omap2_onenand_set_sync_mode(struct 
omap_onenand_platform_data *cfg,
}
 
/* Configure GPMC for synchronous read */
-   gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
- GPMC_CONFIG1_WRAPBURST_SUPP |
- GPMC_CONFIG1_READMULTIPLE_SUPP |
- (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) |
- (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) |
- (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) |
- GPMC_CONFIG1_CLKACTIVATIONTIME(fclk_offset) |
- GPMC_CONFIG1_PAGE_LEN(2) |
- (cpu_is_omap34xx() ? 0 :
-   (GPMC_CONFIG1_WAIT_READ_MON |
-GPMC_CONFIG1_WAIT_PIN_SEL(0

[PATCH 09/39] ARM: OMAP2+: flash: Adapt to gpmc driver

2012-05-01 Thread Afzal Mohammed
gpmc driver has been converted to driver. Modify board_flash_init
so that it can setup gpmc driver platform details for boards

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-3430sdp.c |2 +-
 arch/arm/mach-omap2/board-3630sdp.c |3 +-
 arch/arm/mach-omap2/board-flash.c   |   89 +++
 arch/arm/mach-omap2/board-flash.h   |   11 +++--
 4 files changed, 58 insertions(+), 47 deletions(-)

diff --git a/arch/arm/mach-omap2/board-3430sdp.c 
b/arch/arm/mach-omap2/board-3430sdp.c
index da75f23..ac2e398 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -620,7 +620,7 @@ static void __init omap_3430sdp_init(void)
omap_sdrc_init(hyb18m512160af6_sdrc_params, NULL);
usb_musb_init(NULL);
board_smc91x_init();
-   board_flash_init(sdp_flash_partitions, chip_sel_3430, 0);
+   board_flash_init(sdp_flash_partitions, chip_sel_3430, 0, NULL);
sdp3430_display_init();
enable_board_wakeup_source();
usbhs_init(usbhs_bdata);
diff --git a/arch/arm/mach-omap2/board-3630sdp.c 
b/arch/arm/mach-omap2/board-3630sdp.c
index 6ef350d..74195b7 100644
--- a/arch/arm/mach-omap2/board-3630sdp.c
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -204,7 +204,8 @@ static void __init omap_sdp_init(void)
  h8mbx00u0mer0em_sdrc_params);
zoom_display_init();
board_smc91x_init();
-   board_flash_init(sdp_flash_partitions, chip_sel_sdp, NAND_BUSWIDTH_16);
+   board_flash_init(sdp_flash_partitions, chip_sel_sdp,
+   NAND_BUSWIDTH_16, NULL);
enable_board_wakeup_source();
usbhs_init(usbhs_bdata);
 }
diff --git a/arch/arm/mach-omap2/board-flash.c 
b/arch/arm/mach-omap2/board-flash.c
index 8727c05..8deead9 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -39,46 +39,33 @@ static struct physmap_flash_data board_nor_data = {
.width  = 2,
 };
 
-static struct resource board_nor_resource = {
-   .flags  = IORESOURCE_MEM,
+static struct gpmc_cs_data gpmc_nor_cs_data = {
 };
 
-static struct platform_device board_nor_device = {
+static struct gpmc_device_pdata gpmc_nor_data = {
.name   = physmap-flash,
.id = 0,
-   .dev= {
-   .platform_data = board_nor_data,
-   },
-   .num_resources  = 1,
-   .resource   = board_nor_resource,
+   .cs_data= gpmc_nor_cs_data,
+   .num_cs = 1,
 };
 
-static void
-__init board_nor_init(struct mtd_partition *nor_parts, u8 nr_parts, u8 cs)
+static __init struct gpmc_device_pdata *
+gpmc_nor_init(struct mtd_partition *nor_parts, u8 nr_parts, u8 cs)
 {
-   int err;
-
board_nor_data.parts= nor_parts;
board_nor_data.nr_parts = nr_parts;
 
-   /* Configure start address and size of NOR device */
-   if (omap_rev() = OMAP3430_REV_ES1_0) {
-   err = gpmc_cs_request(cs, FLASH_SIZE_SDPV2 - 1,
-   (unsigned long *)board_nor_resource.start);
-   board_nor_resource.end = board_nor_resource.start
-   + FLASH_SIZE_SDPV2 - 1;
-   } else {
-   err = gpmc_cs_request(cs, FLASH_SIZE_SDPV1 - 1,
-   (unsigned long *)board_nor_resource.start);
-   board_nor_resource.end = board_nor_resource.start
-   + FLASH_SIZE_SDPV1 - 1;
-   }
-   if (err  0) {
-   pr_err(NOR: Can't request GPMC CS\n);
-   return;
-   }
-   if (platform_device_register(board_nor_device)  0)
-   pr_err(Unable to register NOR device\n);
+   gpmc_nor_cs_data.cs = cs;
+
+   if (omap_rev() = OMAP3430_REV_ES1_0)
+   gpmc_nor_cs_data.mem_size = FLASH_SIZE_SDPV2;
+   else
+   gpmc_nor_cs_data.mem_size = FLASH_SIZE_SDPV1;
+
+   gpmc_nor_data.pdata = board_nor_data;
+   gpmc_nor_data.pdata_size = sizeof(board_nor_data);
+
+   return gpmc_nor_data;
 }
 
 #if defined(CONFIG_MTD_ONENAND_OMAP2) || \
@@ -183,8 +170,11 @@ unmap:
  *
  * @return - void.
  */
-void __init board_flash_init(struct flash_partitions partition_info[],
-   char chip_sel_board[][GPMC_CS_NUM], int nand_type)
+__init struct gpmc_device_pdata **board_flash_init(
+   struct flash_partitions partition_info[],
+   char chip_sel_board[][GPMC_CS_NUM],
+   int nand_type,
+   struct gpmc_device_pdata **gpmc_data)
 {
u8  cs = 0;
u8  norcs = GPMC_CS_NUM + 1;
@@ -193,13 +183,18 @@ void __init board_flash_init(struct flash_partitions 
partition_info[],
u8  idx;
unsigned char   *config_sel = NULL;
 
+   if (gpmc_data

[PATCH 10/39] ARM: OMAP2+: gpmc-smsc911x: Adapt to use gpmc driver

2012-05-01 Thread Afzal Mohammed
gpmc has been converted to driver. And all gpmc related
configuration would be done by gpmc driver. Provide
gpmc driver with sufficient information so that it can
configure.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc-smsc911x.c |   59 ---
 arch/arm/plat-omap/include/plat/gpmc-smsc911x.h |9 +++-
 2 files changed, 39 insertions(+), 29 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-smsc911x.c 
b/arch/arm/mach-omap2/gpmc-smsc911x.c
index b6c77be..2c89685 100644
--- a/arch/arm/mach-omap2/gpmc-smsc911x.c
+++ b/arch/arm/mach-omap2/gpmc-smsc911x.c
@@ -24,13 +24,8 @@
 #include plat/gpmc.h
 #include plat/gpmc-smsc911x.h
 
-static struct resource gpmc_smsc911x_resources[] = {
-   [0] = {
-   .flags  = IORESOURCE_MEM,
-   },
-   [1] = {
-   .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-   },
+static struct resource gpmc_smsc911x_resources = {
+   .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
 };
 
 static struct smsc911x_platform_config gpmc_smsc911x_config = {
@@ -44,26 +39,42 @@ static struct smsc911x_platform_config gpmc_smsc911x_config 
= {
  * assume that pin multiplexing is done in the board-*.c file,
  * or in the bootloader.
  */
-void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *gpmc_cfg)
+__init struct gpmc_device_pdata *
+gpmc_smsc911x_init(struct omap_smsc911x_platform_data *gpmc_cfg)
 {
-   struct platform_device *pdev;
-   unsigned long cs_mem_base;
int ret;
+   struct gpmc_device_pdata *gpmc_pdev;
+   struct gpmc_cs_data *gpmc_cs;
 
-   if (gpmc_cs_request(gpmc_cfg-cs, SZ_16M, cs_mem_base)  0) {
-   pr_err(Failed to request GPMC mem region\n);
-   return;
+   gpmc_pdev = kzalloc(sizeof(*gpmc_pdev), GFP_KERNEL);
+   if (gpmc_pdev == NULL)
+   return gpmc_pdev;
+
+   gpmc_cs = kzalloc(sizeof(*gpmc_cs), GFP_KERNEL);
+   if (gpmc_pdev == NULL) {
+   kfree(gpmc_pdev);
+   return NULL;
}
 
-   gpmc_smsc911x_resources[0].start = cs_mem_base + 0x0;
-   gpmc_smsc911x_resources[0].end = cs_mem_base + 0xff;
+   gpmc_pdev-cs_data = gpmc_cs;
+   gpmc_pdev-num_cs = 1;
+   gpmc_pdev-name = smsc911x;
+   gpmc_pdev-id = gpmc_cfg-id;
+   gpmc_pdev-pdata = gpmc_smsc911x_config;
+   gpmc_pdev-pdata_size = sizeof(gpmc_smsc911x_config);
+
+   gpmc_cs-cs = gpmc_cfg-cs;
+   gpmc_cs-mem_size = 0x100;
+
+   gpmc_pdev-per_res = gpmc_smsc911x_resources;
+   gpmc_pdev-per_res_cnt = 1;
 
if (gpio_request_one(gpmc_cfg-gpio_irq, GPIOF_IN, smsc911x irq)) {
pr_err(Failed to request IRQ GPIO%d\n, gpmc_cfg-gpio_irq);
goto free1;
}
 
-   gpmc_smsc911x_resources[1].start = gpio_to_irq(gpmc_cfg-gpio_irq);
+   gpmc_smsc911x_resources.start = gpio_to_irq(gpmc_cfg-gpio_irq);
 
if (gpio_is_valid(gpmc_cfg-gpio_reset)) {
ret = gpio_request_one(gpmc_cfg-gpio_reset,
@@ -81,21 +92,15 @@ void __init gpmc_smsc911x_init(struct 
omap_smsc911x_platform_data *gpmc_cfg)
 
gpmc_smsc911x_config.flags = gpmc_cfg-flags ? : SMSC911X_USE_16BIT;
 
-   pdev = platform_device_register_resndata(NULL, smsc911x, gpmc_cfg-id,
-gpmc_smsc911x_resources, ARRAY_SIZE(gpmc_smsc911x_resources),
-gpmc_smsc911x_config, sizeof(gpmc_smsc911x_config));
-   if (!pdev) {
-   pr_err(Unable to register platform device\n);
-   gpio_free(gpmc_cfg-gpio_reset);
-   goto free2;
-   }
-
-   return;
+   return gpmc_pdev;
 
 free2:
gpio_free(gpmc_cfg-gpio_irq);
 free1:
-   gpmc_cs_free(gpmc_cfg-cs);
+   kfree(gpmc_cs);
+   kfree(gpmc_pdev);
 
pr_err(Could not initialize smsc911x device\n);
+
+   return NULL;
 }
diff --git a/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h 
b/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h
index ea6c9c8..66dc7f1 100644
--- a/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h
+++ b/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h
@@ -11,6 +11,8 @@
  * published by the Free Software Foundation.
  */
 
+#includeplat/gpmc.h
+
 #ifndef __ASM_ARCH_OMAP_GPMC_SMSC911X_H__
 
 struct omap_smsc911x_platform_data {
@@ -23,12 +25,15 @@ struct omap_smsc911x_platform_data {
 
 #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
 
-extern void gpmc_smsc911x_init(struct omap_smsc911x_platform_data *d);
+extern struct gpmc_device_pdata *
+gpmc_smsc911x_init(struct omap_smsc911x_platform_data *d);
 
 #else
 
-static inline void gpmc_smsc911x_init(struct omap_smsc911x_platform_data *d)
+static inline struct gpmc_device_pdata *
+gpmc_smsc911x_init(struct omap_smsc911x_platform_data *d)
 {
+   return NULL;
 }
 
 #endif
-- 
1.7.10

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord

[PATCH 11/39] ARM: OMAP2+: gpmc-smc91x: Adapt to use gpmc driver

2012-05-01 Thread Afzal Mohammed
Currently gpmc is configured in platform for smc91x. As configuring
gpmc has been moved to gpmc driver, populate details needed for the
driver to configure gpmc. gpmc driver would configure based on this
information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-2430sdp.c   |2 +-
 arch/arm/mach-omap2/board-3430sdp.c   |1 +
 arch/arm/mach-omap2/board-3630sdp.c   |1 +
 arch/arm/mach-omap2/gpmc-smc91x.c |   87 +++--
 arch/arm/plat-omap/include/plat/gpmc-smc91x.h |   10 ++-
 5 files changed, 47 insertions(+), 54 deletions(-)

diff --git a/arch/arm/mach-omap2/board-2430sdp.c 
b/arch/arm/mach-omap2/board-2430sdp.c
index e658f83..68679a8 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -175,7 +175,7 @@ static struct omap_smc91x_platform_data board_smc91x_data = 
{
.gpio_irq   = 149,
.flags  = GPMC_MUX_ADD_DATA | GPMC_TIMINGS_SMC91C96 |
IORESOURCE_IRQ_LOWLEVEL,
-
+   .skip_timing= true,
 };
 
 static void __init board_smc91x_init(void)
diff --git a/arch/arm/mach-omap2/board-3430sdp.c 
b/arch/arm/mach-omap2/board-3430sdp.c
index ac2e398..367a466 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -434,6 +434,7 @@ static struct omap_smc91x_platform_data board_smc91x_data = 
{
.cs = 3,
.flags  = GPMC_MUX_ADD_DATA | GPMC_TIMINGS_SMC91C96 |
IORESOURCE_IRQ_LOWLEVEL,
+   .skip_timing= true,
 };
 
 static void __init board_smc91x_init(void)
diff --git a/arch/arm/mach-omap2/board-3630sdp.c 
b/arch/arm/mach-omap2/board-3630sdp.c
index 74195b7..143e47f 100644
--- a/arch/arm/mach-omap2/board-3630sdp.c
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -32,6 +32,7 @@
 static struct omap_smc91x_platform_data board_smc91x_data = {
.cs = 3,
.flags  = GPMC_MUX_ADD_DATA | IORESOURCE_IRQ_LOWLEVEL,
+   .skip_timing= true,
 };
 
 static void __init board_smc91x_init(void)
diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c 
b/arch/arm/mach-omap2/gpmc-smc91x.c
index ba10c24..9389df1 100644
--- a/arch/arm/mach-omap2/gpmc-smc91x.c
+++ b/arch/arm/mach-omap2/gpmc-smc91x.c
@@ -23,13 +23,8 @@
 
 static struct omap_smc91x_platform_data *gpmc_cfg;
 
-static struct resource gpmc_smc91x_resources[] = {
-   [0] = {
-   .flags  = IORESOURCE_MEM,
-   },
-   [1] = {
-   .flags  = IORESOURCE_IRQ,
-   },
+static struct resource gpmc_smc91x_resource = {
+   .flags  = IORESOURCE_IRQ,
 };
 
 static struct smc91x_platdata gpmc_smc91x_info = {
@@ -38,14 +33,17 @@ static struct smc91x_platdata gpmc_smc91x_info = {
.ledb   = RPC_LED_TX_RX,
 };
 
-static struct platform_device gpmc_smc91x_device = {
+static struct gpmc_cs_data gpmc_smc91x_cs_data;
+
+static struct gpmc_device_pdata gpmc_smc91x_data = {
.name   = smc91x,
.id = -1,
-   .dev= {
-   .platform_data = gpmc_smc91x_info,
-   },
-   .num_resources  = ARRAY_SIZE(gpmc_smc91x_resources),
-   .resource   = gpmc_smc91x_resources,
+   .pdata  = gpmc_smc91x_info,
+   .pdata_size = sizeof(gpmc_smc91x_info),
+   .per_res= gpmc_smc91x_resource,
+   .per_res_cnt= 1,
+   .cs_data= gpmc_smc91x_cs_data,
+   .num_cs = 1,
 };
 
 /*
@@ -54,9 +52,10 @@ static struct platform_device gpmc_smc91x_device = {
  * http://www.smsc.com/main/catalog/lan91c96.html
  * REVISIT: Level shifters can add at least to the access latency.
  */
-static int smc91c96_gpmc_retime(void)
+static void smc91c96_gpmc_retime(void)
 {
-   struct gpmc_timings t;
+   /* GPMC timing configuration after this function dies, hence static */
+   static struct gpmc_timings t;
const int t3 = 10;  /* Figure 12.2 read and 12.4 write */
const int t4_r = 20;/* Figure 12.2 read */
const int t4_w = 5; /* Figure 12.4 write */
@@ -65,7 +64,6 @@ static int smc91c96_gpmc_retime(void)
const int t7 = 5;   /* Figure 12.4 write */
const int t8 = 5;   /* Figure 12.4 write */
const int t20 = 185;/* Figure 12.2 read and 12.4 write */
-   u32 l;
 
memset(t, 0, sizeof(t));
 
@@ -93,16 +91,17 @@ static int smc91c96_gpmc_retime(void)
t.cs_wr_off = t.we_off + t4_w;
t.wr_cycle = t20 - t.we_on;
 
-   l = GPMC_CONFIG1_DEVICESIZE_16;
+   gpmc_smc91x_cs_data.have_config = true;
+   gpmc_smc91x_cs_data.config = GPMC_DEVICESIZE_16;
if (gpmc_cfg-flags  GPMC_MUX_ADD_DATA)
-   l |= GPMC_CONFIG1_MUXADDDATA;
+   gpmc_smc91x_cs_data.config |= GPMC_MUXADDDATA;
if (gpmc_cfg-flags  GPMC_READ_MON)
-   l |= GPMC_CONFIG1_WAIT_READ_MON

[PATCH 12/39] ARM: OMAP2+: gpmc-tusb6010: Adapt to gpmc driver

2012-05-01 Thread Afzal Mohammed
Currently gpmc is configured in platform for tusb6010. As configuring
gpmc has been moved to gpmc driver, populate details needed for the
driver to configure gpmc. gpmc driver would configure based on this
information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/usb-tusb6010.c |  177 ++--
 include/linux/usb/musb.h   |4 +-
 2 files changed, 70 insertions(+), 111 deletions(-)

diff --git a/arch/arm/mach-omap2/usb-tusb6010.c 
b/arch/arm/mach-omap2/usb-tusb6010.c
index db84a46..d7817d2 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -22,6 +22,24 @@
 
 #include mux.h
 
+static struct resource tusb_resources = {
+   .name   = mc,
+   .flags  = IORESOURCE_IRQ,
+};
+
+#defineTUSB_GPMC_CS_ASYNC_IDX  1
+#defineTUSB_GPMC_CS_SYNC_IDX   2
+#defineTUSB_GPMC_CS_NUM2
+
+static struct gpmc_cs_data gpmc_tusb_cs_data[TUSB_GPMC_CS_NUM];
+
+static struct gpmc_device_pdata gpmc_tusb_data = {
+   .name   = musb-tusb,
+   .id = -1,
+   .per_res= tusb_resources,
+   .per_res_cnt= 1,
+};
+
 static u8  async_cs, sync_cs;
 static unsignedrefclk_psec;
 
@@ -51,9 +69,9 @@ next_clk(unsigned t1_NS, unsigned t2_ps, unsigned fclk_ps)
 
 /* NOTE:  timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */
 
-static int tusb_set_async_mode(unsigned sysclk_ps, unsigned fclk_ps)
+static void tusb_set_async_mode(unsigned sysclk_ps, unsigned fclk_ps)
 {
-   struct gpmc_timings t;
+   static struct gpmc_timings t;
unsignedt_acsnh_advnh = sysclk_ps + 3000;
unsignedtmp;
 
@@ -106,12 +124,12 @@ static int tusb_set_async_mode(unsigned sysclk_ps, 
unsigned fclk_ps)
tmp = t.cs_wr_off * 1000 + 7000 /* t_acsn_rdy_z */;
t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
 
-   return gpmc_cs_set_timings(async_cs, t);
+   gpmc_tusb_cs_data[TUSB_GPMC_CS_ASYNC_IDX].timing = t;
 }
 
 static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned fclk_ps)
 {
-   struct gpmc_timings t;
+   static struct gpmc_timings t;
unsignedt_scsnh_advnh = sysclk_ps + 3000;
unsignedtmp;
 
@@ -174,71 +192,30 @@ static int tusb_set_sync_mode(unsigned sysclk_ps, 
unsigned fclk_ps)
tmp = t.cs_wr_off * 1000 + 7000 /* t_scsn_rdy_z */;
t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
 
-   return gpmc_cs_set_timings(sync_cs, t);
+   gpmc_tusb_cs_data[TUSB_GPMC_CS_SYNC_IDX].timing = t;
+
+   return 0;
 }
 
 extern unsigned long gpmc_get_fclk_period(void);
 
 /* tusb driver calls this when it changes the chip's clocking */
-int tusb6010_platform_retime(unsigned is_refclk)
+static int tusb6010_platform_retime(unsigned is_refclk)
 {
-   static const char   error[] =
-   KERN_ERR tusb6010 %s retime error %d\n;
-
unsignedfclk_ps = gpmc_get_fclk_period();
unsignedsysclk_ps;
-   int status;
 
if (!refclk_psec || fclk_ps == 0)
return -ENODEV;
 
sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60;
 
-   status = tusb_set_async_mode(sysclk_ps, fclk_ps);
-   if (status  0) {
-   printk(error, async, status);
-   goto done;
-   }
-   status = tusb_set_sync_mode(sysclk_ps, fclk_ps);
-   if (status  0)
-   printk(error, sync, status);
-done:
-   return status;
+   tusb_set_async_mode(sysclk_ps, fclk_ps);
+   return tusb_set_sync_mode(sysclk_ps, fclk_ps);
 }
-EXPORT_SYMBOL_GPL(tusb6010_platform_retime);
-
-static struct resource tusb_resources[] = {
-   /* Order is significant!  The start/end fields
-* are updated during setup..
-*/
-   { /* Asynchronous access */
-   .flags  = IORESOURCE_MEM,
-   },
-   { /* Synchronous access */
-   .flags  = IORESOURCE_MEM,
-   },
-   { /* IRQ */
-   .name   = mc,
-   .flags  = IORESOURCE_IRQ,
-   },
-};
-
-static u64 tusb_dmamask = ~(u32)0;
-
-static struct platform_device tusb_device = {
-   .name   = musb-tusb,
-   .id = -1,
-   .dev = {
-   .dma_mask   = tusb_dmamask,
-   .coherent_dma_mask  = 0x,
-   },
-   .num_resources  = ARRAY_SIZE(tusb_resources),
-   .resource   = tusb_resources,
-};
-
 
 /* this may be called only from board-*.c setup code */
-int __init
+__init struct gpmc_device_pdata *
 tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
unsigned ps_refclk, unsigned waitpin,
unsigned async, unsigned sync,
@@ -249,82 +226,72 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data 
*data,
KERN_ERR tusb6010 init error %d, %d\n

[PATCH 13/39] ARM: OMAP3: hwmod data: add gpmc

2012-05-01 Thread Afzal Mohammed
Add gpmc hwmod and associated interconnect data

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |   52 
 1 file changed, 52 insertions(+)

diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 0c65079..4da8394 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -1981,6 +1981,40 @@ static struct omap_hwmod omap3xxx_usb_tll_hs_hwmod = {
 };
 
 /*
+ * 'gpmc' class
+ * general purpose memory controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap3xxx_gpmc_sysc = {
+   .rev_offs   = 0x,
+   .sysc_offs  = 0x0010,
+   .syss_offs  = 0x0014,
+   .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE |
+  SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+   .idlemodes  = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+   .sysc_fields= omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_gpmc_hwmod_class = {
+   .name   = gpmc,
+   .sysc   = omap3xxx_gpmc_sysc,
+};
+
+static struct omap_hwmod_irq_info omap3xxx_gpmc_irqs[] = {
+   { .irq = 20 },
+   { .irq = -1 }
+};
+
+static struct omap_hwmod omap3xxx_gpmc_hwmod = {
+   .name   = gpmc,
+   .class  = omap3xxx_gpmc_hwmod_class,
+   .clkdm_name = l3_init_clkdm,
+   .mpu_irqs   = omap3xxx_gpmc_irqs,
+   .main_clk   = gpmc_fck,
+   .flags  = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
+};
+
+/*
  * interfaces
  */
 
@@ -3059,6 +3093,23 @@ static struct omap_hwmod_ocp_if 
omap3xxx_l4_core__usb_tll_hs = {
.user   = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+static struct omap_hwmod_addr_space omap3xxx_gpmc_addrs[] = {
+   {
+   .pa_start   = 0x6E00,
+   .pa_end = 0x6E000FFF,
+   .flags  = ADDR_TYPE_RT
+   },
+   { }
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l3_main__gpmc = {
+   .master = omap3xxx_l3_main_hwmod,
+   .slave  = omap3xxx_gpmc_hwmod,
+   .clk= core_l3_ick,
+   .addr   = omap3xxx_gpmc_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,
@@ -3103,6 +3154,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] 
__initdata = {
omap34xx_l4_core__mcspi2,
omap34xx_l4_core__mcspi3,
omap34xx_l4_core__mcspi4,
+   omap3xxx_l3_main__gpmc,
NULL,
 };
 
-- 
1.7.10

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


[PATCH 14/39] ARM: OMAP2xxx: hwmod data: add gpmc

2012-05-01 Thread Afzal Mohammed
Add gpmc hwmod and associated interconnect data

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/omap_hwmod_2420_data.c |   18 +
 arch/arm/mach-omap2/omap_hwmod_2430_data.c |   18 +
 arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c |   41 
 arch/arm/mach-omap2/omap_hwmod_common_data.h   |1 +
 arch/arm/mach-omap2/prcm-common.h  |2 +
 5 files changed, 80 insertions(+)

diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c 
b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index 2c087ff..55c8c7b 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -428,6 +428,23 @@ static struct omap_hwmod_ocp_if omap2420_l4_core__mcbsp2 = 
{
.user   = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+static struct omap_hwmod_addr_space omap2420_gpmc_addrs[] = {
+   {
+   .pa_start   = 0x6800A000,
+   .pa_end = 0x6800AFFF,
+   .flags  = ADDR_TYPE_RT
+   },
+   { }
+};
+
+static struct omap_hwmod_ocp_if omap2420_l3__gpmc = {
+   .master = omap2xxx_l3_main_hwmod,
+   .slave  = omap2xxx_gpmc_hwmod,
+   .clk= core_l3_ck,
+   .addr   = omap2420_gpmc_addrs,
+   .user   = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 static struct omap_hwmod_ocp_if *omap2420_hwmod_ocp_ifs[] __initdata = {
omap2xxx_l3_main__l4_core,
omap2xxx_mpu__l3_main,
@@ -468,6 +485,7 @@ static struct omap_hwmod_ocp_if *omap2420_hwmod_ocp_ifs[] 
__initdata = {
omap2420_l4_core__mailbox,
omap2420_l4_core__mcbsp1,
omap2420_l4_core__mcbsp2,
+   omap2420_l3__gpmc,
NULL,
 };
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c 
b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index 71d9f88..dd224cca 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -838,6 +838,23 @@ static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp5 = 
{
.user   = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+static struct omap_hwmod_addr_space omap2430_gpmc_addrs[] = {
+   {
+   .pa_start   = 0x6E00,
+   .pa_end = 0x6E000FFF,
+   .flags  = ADDR_TYPE_RT
+   },
+   { }
+};
+
+static struct omap_hwmod_ocp_if omap2430_l3__gpmc = {
+   .master = omap2xxx_l3_main_hwmod,
+   .slave  = omap2xxx_gpmc_hwmod,
+   .clk= core_l3_ck,
+   .addr   = omap2430_gpmc_addrs,
+   .user   = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 static struct omap_hwmod_ocp_if *omap2430_hwmod_ocp_ifs[] __initdata = {
omap2xxx_l3_main__l4_core,
omap2xxx_mpu__l3_main,
@@ -886,6 +903,7 @@ static struct omap_hwmod_ocp_if *omap2430_hwmod_ocp_ifs[] 
__initdata = {
omap2430_l4_core__mcbsp3,
omap2430_l4_core__mcbsp4,
omap2430_l4_core__mcbsp5,
+   omap2430_l3__gpmc,
NULL,
 };
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c 
b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
index 45aaa07..e75da40 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
@@ -175,6 +175,26 @@ struct omap_hwmod_class omap2xxx_mcspi_class = {
 };
 
 /*
+ * 'gpmc' class
+ * general purpose memory controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap2xxx_gpmc_sysc = {
+   .rev_offs   = 0x,
+   .sysc_offs  = 0x0010,
+   .syss_offs  = 0x0014,
+   .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE |
+  SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+   .idlemodes  = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+   .sysc_fields= omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2xxx_gpmc_hwmod_class = {
+   .name   = gpmc,
+   .sysc   = omap2xxx_gpmc_sysc,
+};
+
+/*
  * IP blocks
  */
 
@@ -732,3 +752,24 @@ struct omap_hwmod omap2xxx_mcspi2_hwmod = {
.class  = omap2xxx_mcspi_class,
.dev_attr   = omap_mcspi2_dev_attr,
 };
+
+/* gpmc */
+static struct omap_hwmod_irq_info omap2xxx_gpmc_irqs[] = {
+   { .irq = 20 },
+   { .irq = -1 }
+};
+
+struct omap_hwmod omap2xxx_gpmc_hwmod = {
+   .name   = gpmc,
+   .class  = omap2xxx_gpmc_hwmod_class,
+   .mpu_irqs   = omap2xxx_gpmc_irqs,
+   .main_clk   = gpmc_fck,
+   .flags  = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
+   .prcm   = {
+   .omap2  = {
+   .prcm_reg_id = 3,
+   .module_bit = OMAP24XX_EN_GPMC_MASK,
+   .module_offs = CORE_MOD,
+   },
+   },
+};
diff --git a/arch/arm/mach-omap2/omap_hwmod_common_data.h 
b/arch/arm/mach-omap2/omap_hwmod_common_data.h
index 7aa9156..63e0134

[PATCH 15/39] mtd: nand: omap2: obtain memory from resource

2012-05-01 Thread Afzal Mohammed
gpmc being converted to driver, provides drivers
of peripheral connected memory space used by the
peripheral as memory resource.

Modify nand omap driver to obtain memory detials
from resource structure.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/plat-omap/include/plat/nand.h |1 -
 drivers/mtd/nand/omap2.c   |   20 ++--
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/nand.h 
b/arch/arm/plat-omap/include/plat/nand.h
index 30c61c9..570c4f4 100644
--- a/arch/arm/plat-omap/include/plat/nand.h
+++ b/arch/arm/plat-omap/include/plat/nand.h
@@ -26,7 +26,6 @@ struct omap_nand_platform_data {
booldev_ready;
int gpmc_irq;
enum nand_ioxfer_type;
-   unsigned long   phys_base;
int devsize;
enum omap_ecc   ecc_opt;
struct gpmc_nand_regs   reg;
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index c2b0bba..be4b321 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -118,6 +118,7 @@ struct omap_nand_info {
 
int gpmc_cs;
unsigned long   phys_base;
+   unsigned long   mem_size;
struct completion   comp;
int dma_ch;
int gpmc_irq;
@@ -931,6 +932,7 @@ static int __devinit omap_nand_probe(struct platform_device 
*pdev)
struct omap_nand_platform_data  *pdata;
int err;
int i, offset;
+   struct resource *res;
 
pdata = pdev-dev.platform_data;
if (pdata == NULL) {
@@ -950,7 +952,6 @@ static int __devinit omap_nand_probe(struct platform_device 
*pdev)
info-pdev = pdev;
 
info-gpmc_cs   = pdata-cs;
-   info-phys_base = pdata-phys_base;
 
info-mtd.priv  = info-nand;
info-mtd.name  = dev_name(pdev-dev);
@@ -959,16 +960,23 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
info-nand.options  = pdata-devsize;
info-nand.options  |= NAND_SKIP_BBTSCAN;
 
-   /* NAND write protect off */
-   gpmc_cs_configure(info-gpmc_cs, GPMC_CONFIG_WP, 0);
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   if (res == NULL) {
+   err = -EINVAL;
+   dev_err(pdev-dev, error getting memory resource\n);
+   goto out_free_info;
+   }
+
+   info-phys_base = res-start;
+   info-mem_size = resource_size(res);
 
-   if (!request_mem_region(info-phys_base, NAND_IO_SIZE,
+   if (!request_mem_region(info-phys_base, info-mem_size,
pdev-dev.driver-name)) {
err = -EBUSY;
goto out_free_info;
}
 
-   info-nand.IO_ADDR_R = ioremap(info-phys_base, NAND_IO_SIZE);
+   info-nand.IO_ADDR_R = ioremap(info-phys_base, info-mem_size);
if (!info-nand.IO_ADDR_R) {
err = -ENOMEM;
goto out_release_mem_region;
@@ -1110,7 +1118,7 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
return 0;
 
 out_release_mem_region:
-   release_mem_region(info-phys_base, NAND_IO_SIZE);
+   release_mem_region(info-phys_base, info-mem_size);
 out_free_info:
kfree(info);
 
-- 
1.7.10

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


[PATCH 16/39] mtd: nand: omap2: use gpmc provided irqs

2012-05-01 Thread Afzal Mohammed
GPMC driver provides it's clientsd with interrupts that can be used
through struct resource. Make use of it for irq mode functionality.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 drivers/mtd/nand/omap2.c |   67 +-
 1 file changed, 42 insertions(+), 25 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index be4b321..440536b 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -121,7 +121,8 @@ struct omap_nand_info {
unsigned long   mem_size;
struct completion   comp;
int dma_ch;
-   int gpmc_irq;
+   int gpmc_irq_fifo;
+   int gpmc_irq_count;
enum {
OMAP_NAND_IO_READ = 0,  /* read */
OMAP_NAND_IO_WRITE, /* write */
@@ -472,13 +473,11 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev)
 {
struct omap_nand_info *info = (struct omap_nand_info *) dev;
u32 bytes;
-   u32 irq_stat;
 
-   irq_stat = gpmc_read_status(GPMC_GET_IRQ_STATUS);
bytes = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT);
bytes = bytes   0xFFFC; /* io in multiple of 4 bytes */
if (info-iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */
-   if (irq_stat  0x2)
+   if (this_irq == info-gpmc_irq_count)
goto done;
 
if (info-buf_len  (info-buf_len  bytes))
@@ -495,20 +494,17 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev)
(u32 *)info-buf, bytes  2);
info-buf = info-buf + bytes;
 
-   if (irq_stat  0x2)
+   if (this_irq == info-gpmc_irq_count)
goto done;
}
-   gpmc_cs_configure(info-gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat);
 
return IRQ_HANDLED;
 
 done:
complete(info-comp);
-   /* disable irq */
-   gpmc_cs_configure(info-gpmc_cs, GPMC_ENABLE_IRQ, 0);
 
-   /* clear status */
-   gpmc_cs_configure(info-gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat);
+   disable_irq_nosync(info-gpmc_irq_fifo);
+   disable_irq_nosync(info-gpmc_irq_count);
 
return IRQ_HANDLED;
 }
@@ -542,9 +538,9 @@ static void omap_read_buf_irq_pref(struct mtd_info *mtd, 
u_char *buf, int len)
goto out_copy;
 
info-buf_len = len;
-   /* enable irq */
-   gpmc_cs_configure(info-gpmc_cs, GPMC_ENABLE_IRQ,
-   (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT));
+
+   enable_irq(info-gpmc_irq_count);
+   enable_irq(info-gpmc_irq_fifo);
 
/* waiting for read to complete */
wait_for_completion(info-comp);
@@ -591,12 +587,13 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd,
goto out_copy;
 
info-buf_len = len;
-   /* enable irq */
-   gpmc_cs_configure(info-gpmc_cs, GPMC_ENABLE_IRQ,
-   (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT));
+
+   enable_irq(info-gpmc_irq_count);
+   enable_irq(info-gpmc_irq_fifo);
 
/* waiting for write to complete */
wait_for_completion(info-comp);
+
/* wait for data to flushed-out before reset the prefetch */
tim = 0;
limit = (loops_per_jiffy *  msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS));
@@ -982,6 +979,14 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
goto out_release_mem_region;
}
 
+   info-gpmc_irq_fifo = platform_get_irq(pdev, 0);
+   if (info-gpmc_irq_fifo == -ENXIO)
+   dev_warn(pdev-dev, error getting FIFO IRQ\n);
+
+   info-gpmc_irq_count = platform_get_irq(pdev, 1);
+   if (info-gpmc_irq_fifo == -ENXIO)
+   dev_warn(pdev-dev, error getting TERMINALCOUNT IRQ\n);
+
info-nand.controller = info-controller;
 
info-nand.IO_ADDR_W = info-nand.IO_ADDR_R;
@@ -1037,17 +1042,24 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
break;
 
case NAND_OMAP_PREFETCH_IRQ:
-   err = request_irq(pdata-gpmc_irq,
-   omap_nand_irq, IRQF_SHARED, gpmc-nand, info);
+   err = request_irq(info-gpmc_irq_fifo,  omap_nand_irq,
+   IRQF_SHARED, gpmc-nand-fifo, info);
if (err) {
dev_err(pdev-dev, requesting irq(%d) error:%d,
-   pdata-gpmc_irq, err);
+   info-gpmc_irq_fifo, err);
goto out_release_mem_region;
-   } else {
-   info-gpmc_irq   = pdata-gpmc_irq;
-   info-nand.read_buf  = omap_read_buf_irq_pref;
-   info-nand.write_buf

[PATCH 17/39] mtd: nand: omap2: handle nand on gpmc

2012-05-01 Thread Afzal Mohammed
GPMC driver has been modified to fill NAND platform data with GPMC
NAND register details. As these registers are accessible in NAND
driver itself, configure NAND in GPMC by itself.

Note: Verfying that other CS have not yet enabled for prefetch  ecc
has to be incorporated. Currently this causes no issues as there are
no boards that use NAND on multiple CS. With GPMC modifications,
perhaps it would be better to consider NAND connected on multiple CS
as a single peripheral using multiple CS. This would make handling
multiple CS issues easier.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 drivers/mtd/nand/omap2.c |  209 --
 1 file changed, 165 insertions(+), 44 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 440536b..34fb726 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -129,8 +129,79 @@ struct omap_nand_info {
} iomode;
u_char  *buf;
int buf_len;
+   struct gpmc_nand_regs   reg;
 };
 
+#definePREFETCH_CONFIG1_CS_SHIFT   24
+#defineECC_CONFIG_CS_SHIFT 1
+#defineCS_MASK 0x7
+#defineENABLE_PREFETCH (0x1  7)
+#defineDMA_MPU_MODE_SHIFT  2
+#defineECCSIZE1_SHIFT  22
+#defineECC1RESULTSIZE  0x1
+#defineECC_CLEAR_SHIFT 8
+#defineECC10x1
+
+/**
+ * omap_prefetch_enable - configures and starts prefetch transfer
+ * @cs: cs (chip select) number
+ * @fifo_th: fifo threshold to be used for read/ write
+ * @dma_mode: dma mode enable (1) or disable (0)
+ * @u32_count: number of bytes to be transferred
+ * @is_write: prefetch read(0) or write post(1) mode
+ */
+static int omap_prefetch_enable(int cs, int fifo_th, int dma_mode,
+   unsigned int u32_count, int is_write, struct omap_nand_info *info)
+{
+   u32 val;
+
+   if (fifo_th  PREFETCH_FIFOTHRESHOLD_MAX) {
+   pr_err(gpmc: fifo threshold is not supported\n);
+   return -1;
+   } else if (!(readl(info-reg.gpmc_prefetch_control))) {
+   /* Set the amount of bytes to be prefetched */
+   writel(u32_count, info-reg.gpmc_prefetch_config2);
+
+   /* Set dma/mpu mode, the prefetch read / post write and
+* enable the engine. Set which cs is has requested for.
+*/
+   val = ((cs  PREFETCH_CONFIG1_CS_SHIFT) |
+   PREFETCH_FIFOTHRESHOLD(fifo_th) |
+   ENABLE_PREFETCH |
+   (dma_mode  DMA_MPU_MODE_SHIFT) |
+   (0x1  is_write));
+   writel(val, info-reg.gpmc_prefetch_config1);
+
+   /*  Start the prefetch engine */
+   writel(0x1, info-reg.gpmc_prefetch_control);
+   } else {
+   return -EBUSY;
+   }
+
+   return 0;
+}
+
+/**
+ * omap_prefetch_reset - disables and stops the prefetch engine
+ */
+static int omap_prefetch_reset(int cs, struct omap_nand_info *info)
+{
+   u32 config1;
+
+   /* check if the same module/cs is trying to reset */
+   config1 = readl(info-reg.gpmc_prefetch_config1);
+   if (((config1  PREFETCH_CONFIG1_CS_SHIFT)  CS_MASK) != cs)
+   return -EINVAL;
+
+   /* Stop the PFPW engine */
+   writel(0x0, info-reg.gpmc_prefetch_control);
+
+   /* Reset/disable the PFPW engine */
+   writel(0x0, info-reg.gpmc_prefetch_config1);
+
+   return 0;
+}
+
 /**
  * omap_hwcontrol - hardware specific access to control-lines
  * @mtd: MTD device structure
@@ -149,13 +220,13 @@ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, 
unsigned int ctrl)
 
if (cmd != NAND_CMD_NONE) {
if (ctrl  NAND_CLE)
-   gpmc_nand_write(info-gpmc_cs, GPMC_NAND_COMMAND, cmd);
+   writeb(cmd, info-reg.gpmc_nand_command);
 
else if (ctrl  NAND_ALE)
-   gpmc_nand_write(info-gpmc_cs, GPMC_NAND_ADDRESS, cmd);
+   writeb(cmd, info-reg.gpmc_nand_address);
 
else /* NAND_NCE */
-   gpmc_nand_write(info-gpmc_cs, GPMC_NAND_DATA, cmd);
+   writeb(cmd, info-reg.gpmc_nand_data);
}
 }
 
@@ -189,7 +260,8 @@ static void omap_write_buf8(struct mtd_info *mtd, const 
u_char *buf, int len)
iowrite8(*p++, info-nand.IO_ADDR_W);
/* wait until buffer is available for write */
do {
-   status = gpmc_read_status(GPMC_STATUS_BUFFER);
+   status = readl(info-reg.gpmc_status) 
+   GPMC_STATUS_BUFF_EMPTY;
} while (!status

[PATCH 18/39] mtd: onenand: omap: obtain memory from resource

2012-05-01 Thread Afzal Mohammed
gpmc being converted to driver, provides drivers of peripheral
connected memory space used by the peripheral as memory resource.
Modify nand omap driver to obtain memory detials from resource
structure. And so remove usage of gpmc exported symbols.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 drivers/mtd/onenand/omap2.c |   29 -
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 398a827..3ff893d 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -48,13 +48,13 @@
 
 #define DRIVER_NAME omap2-onenand
 
-#define ONENAND_IO_SIZESZ_128K
 #define ONENAND_BUFRAM_SIZE(1024 * 5)
 
 struct omap2_onenand {
struct platform_device *pdev;
int gpmc_cs;
unsigned long phys_base;
+   unsigned int mem_size;
int gpio_irq;
struct mtd_info mtd;
struct onenand_chip onenand;
@@ -626,6 +626,7 @@ static int __devinit omap2_onenand_probe(struct 
platform_device *pdev)
struct omap2_onenand *c;
struct onenand_chip *this;
int r;
+   struct resource *res;
 
pdata = pdev-dev.platform_data;
if (pdata == NULL) {
@@ -647,20 +648,24 @@ static int __devinit omap2_onenand_probe(struct 
platform_device *pdev)
c-gpio_irq = 0;
}
 
-   r = gpmc_cs_request(c-gpmc_cs, ONENAND_IO_SIZE, c-phys_base);
-   if (r  0) {
-   dev_err(pdev-dev, Cannot request GPMC CS\n);
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   if (res == NULL) {
+   r = -EINVAL;
+   dev_err(pdev-dev, error getting memory resource\n);
goto err_kfree;
}
 
-   if (request_mem_region(c-phys_base, ONENAND_IO_SIZE,
+   c-phys_base = res-start;
+   c-mem_size = resource_size(res);
+
+   if (request_mem_region(c-phys_base, c-mem_size,
   pdev-dev.driver-name) == NULL) {
-   dev_err(pdev-dev, Cannot reserve memory region at 0x%08lx, 
-   size: 0x%x\n, c-phys_base, ONENAND_IO_SIZE);
+   dev_err(pdev-dev, Cannot reserve memory region at 0x%08lx, 
size: 0x%x\n,
+   c-phys_base, c-mem_size);
r = -EBUSY;
-   goto err_free_cs;
+   goto err_kfree;
}
-   c-onenand.base = ioremap(c-phys_base, ONENAND_IO_SIZE);
+   c-onenand.base = ioremap(c-phys_base, c-mem_size);
if (c-onenand.base == NULL) {
r = -ENOMEM;
goto err_release_mem_region;
@@ -776,9 +781,7 @@ err_release_gpio:
 err_iounmap:
iounmap(c-onenand.base);
 err_release_mem_region:
-   release_mem_region(c-phys_base, ONENAND_IO_SIZE);
-err_free_cs:
-   gpmc_cs_free(c-gpmc_cs);
+   release_mem_region(c-phys_base, c-mem_size);
 err_kfree:
kfree(c);
 
@@ -800,7 +803,7 @@ static int __devexit omap2_onenand_remove(struct 
platform_device *pdev)
gpio_free(c-gpio_irq);
}
iounmap(c-onenand.base);
-   release_mem_region(c-phys_base, ONENAND_IO_SIZE);
+   release_mem_region(c-phys_base, c-mem_size);
gpmc_cs_free(c-gpmc_cs);
kfree(c);
 
-- 
1.7.10

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


[PATCH 19/39] ARM: OMAP2+: board omap3evm: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board
code to provide gpmc driver with required information

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-omap3evm.c |   14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/board-omap3evm.c 
b/arch/arm/mach-omap2/board-omap3evm.c
index fd1b481..b00765e 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -43,6 +43,7 @@
 
 #include plat/board.h
 #include plat/usb.h
+#include plat/gpmc.h
 #include common.h
 #include plat/mcspi.h
 #include video/omapdss.h
@@ -102,6 +103,12 @@ static void __init omap3_evm_get_revision(void)
}
 }
 
+static struct gpmc_device_pdata *gpmc_device_data[1];
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
+};
+
 #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
 #include plat/gpmc-smsc911x.h
 
@@ -122,7 +129,11 @@ static inline void __init omap3evm_init_smsc911x(void)
smsc911x_cfg.gpio_reset = OMAP3EVM_GEN2_ETHR_GPIO_RST;
}
 
-   gpmc_smsc911x_init(smsc911x_cfg);
+   *gpmc_device_data = gpmc_smsc911x_init(smsc911x_cfg);
+   if (*gpmc_device_data)
+   gpmc_data.num_device++;
+   else
+   pr_err(error: unable to initilaize gpmc smsc911x\n);
 }
 
 #else
@@ -679,6 +690,7 @@ static void __init omap3_evm_init(void)
usbhs_init(usbhs_bdata);
omap_ads7846_init(1, OMAP3_EVM_TS_GPIO, 310, NULL);
omap3evm_init_smsc911x();
+   omap_init_gpmc(gpmc_data);
omap3_evm_display_init();
omap3_evm_wl12xx_init();
 }
-- 
1.7.10

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


[PATCH 20/39] ARM: OMAP2+: board omap3beagle: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board
code to provide gpmc driver with required information

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-omap3beagle.c |   18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/board-omap3beagle.c 
b/arch/arm/mach-omap2/board-omap3beagle.c
index 671ac1c..74bc7f6 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -517,8 +517,16 @@ static void __init beagle_opp_init(void)
return;
 }
 
+static struct gpmc_device_pdata *gpmc_device_data[1];
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
+};
+
 static void __init omap3_beagle_init(void)
 {
+   struct omap_nand_platform_data *nand_data;
+
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
omap3_beagle_init_rev();
 
@@ -543,9 +551,17 @@ static void __init omap3_beagle_init(void)
 
usb_musb_init(NULL);
usbhs_init(usbhs_bdata);
-   board_nand_init(omap3beagle_nand_partitions,
+   nand_data = board_nand_init(omap3beagle_nand_partitions,
ARRAY_SIZE(omap3beagle_nand_partitions), GPMC_CS_NUM,
NAND_BUSWIDTH_16, NULL);
+   if (nand_data != NULL) {
+   *gpmc_device_data = gpmc_nand_init(nand_data);
+   if (*gpmc_device_data)
+   gpmc_data.num_device++;
+   } else
+   pr_err(error: %s: nand init\n, __func__);
+
+   omap_init_gpmc(gpmc_data);
 
/* Ensure msecure is mux'd to be able to set the RTC. */
omap_mux_init_signal(sys_drm_msecure, OMAP_PIN_OFF_OUTPUT_HIGH);
-- 
1.7.10

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


[PATCH 21/39] ARM: OMAP2+: board apollon: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board code to
provide gpmc driver with required information. It is believed that
apollon board was added before gpmc-smc91x helper functions were
added. Reuse the now available gpmc_smc91x_init adapted for gpmc
driver.

Note: Timing values were hardcoded and written onto registers,
whether making use of gpmc_smc91x_init would configure timing
properly has to be tested.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-apollon.c |  152 +--
 1 file changed, 38 insertions(+), 114 deletions(-)

diff --git a/arch/arm/mach-omap2/board-apollon.c 
b/arch/arm/mach-omap2/board-apollon.c
index 768ece2..6a402e1 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -39,6 +39,7 @@
 #include plat/board.h
 #include common.h
 #include plat/gpmc.h
+#include plat/gpmc-smc91x.h
 
 #include video/omapdss.h
 #include video/omap-panel-generic-dpi.h
@@ -58,6 +59,12 @@
 #define APOLLON_ETH_CS 1
 #define APOLLON_ETHR_GPIO_IRQ  74
 
+static struct gpmc_device_pdata *gpmc_device_data[2];
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
+};
+
 static struct mtd_partition apollon_partitions[] = {
{
.name   = X-Loader + U-Boot,
@@ -97,57 +104,26 @@ static struct onenand_platform_data apollon_flash_data = {
.nr_parts   = ARRAY_SIZE(apollon_partitions),
 };
 
-static struct resource apollon_flash_resource[] = {
-   [0] = {
-   .flags  = IORESOURCE_MEM,
-   },
+static struct gpmc_cs_data apollon_gpmc_onenand_cs_data = {
+   .cs = APOLLON_FLASH_CS,
+   .mem_size   = SZ_128K,
 };
 
-static struct platform_device apollon_onenand_device = {
+static struct gpmc_device_pdata apollon_gpmc_onenand_data = {
.name   = onenand-flash,
.id = -1,
-   .dev= {
-   .platform_data  = apollon_flash_data,
-   },
-   .num_resources  = ARRAY_SIZE(apollon_flash_resource),
-   .resource   = apollon_flash_resource,
-};
-
-static void __init apollon_flash_init(void)
-{
-   unsigned long base;
-
-   if (gpmc_cs_request(APOLLON_FLASH_CS, SZ_128K, base)  0) {
-   printk(KERN_ERR Cannot request OneNAND GPMC CS\n);
-   return;
-   }
-   apollon_flash_resource[0].start = base;
-   apollon_flash_resource[0].end   = base + SZ_128K - 1;
-}
-
-static struct smc91x_platdata appolon_smc91x_info = {
-   .flags  = SMC91X_USE_16BIT | SMC91X_NOWAIT,
-   .leda   = RPC_LED_100_10,
-   .ledb   = RPC_LED_TX_RX,
+   .pdata  = apollon_flash_data,
+   .pdata_size = sizeof(apollon_flash_data),
+   .cs_data= apollon_gpmc_onenand_cs_data,
+   .num_cs = 1,
 };
 
-static struct resource apollon_smc91x_resources[] = {
-   [0] = {
-   .flags  = IORESOURCE_MEM,
-   },
-   [1] = {
-   .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
-   },
-};
-
-static struct platform_device apollon_smc91x_device = {
-   .name   = smc91x,
-   .id = -1,
-   .dev= {
-   .platform_data  = appolon_smc91x_info,
-   },
-   .num_resources  = ARRAY_SIZE(apollon_smc91x_resources),
-   .resource   = apollon_smc91x_resources,
+static struct omap_smc91x_platform_data apollon_smc91x_data = {
+   .gpio_irq   = APOLLON_ETHR_GPIO_IRQ,
+   .cs = APOLLON_ETH_CS,
+   .wait_pin   = GPMC_WAITPIN_1,
+   .flags  = GPMC_TIMINGS_SMC91C96 | IORESOURCE_IRQ_HIGHEDGE |
+   GPMC_MUXADDDATA,
 };
 
 static struct omap_led_config apollon_led_config[] = {
@@ -185,74 +161,9 @@ static struct platform_device apollon_led_device = {
 };
 
 static struct platform_device *apollon_devices[] __initdata = {
-   apollon_onenand_device,
-   apollon_smc91x_device,
apollon_led_device,
 };
 
-static inline void __init apollon_init_smc91x(void)
-{
-   unsigned long base;
-
-   unsigned int rate;
-   struct clk *gpmc_fck;
-   int eth_cs;
-   int err;
-
-   gpmc_fck = clk_get(NULL, gpmc_fck);   /* Always on ENABLE_ON_INIT */
-   if (IS_ERR(gpmc_fck)) {
-   WARN_ON(1);
-   return;
-   }
-
-   clk_enable(gpmc_fck);
-   rate = clk_get_rate(gpmc_fck);
-
-   eth_cs = APOLLON_ETH_CS;
-
-   /* Make sure CS1 timings are correct */
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1, 0x00011200);
-
-   if (rate = 16000) {
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01);
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803);
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a);
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
-   gpmc_cs_write_reg(eth_cs

[PATCH 22/39] ARM: OMAP2+: board h4: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board
code to provide gpmc driver with required information.
Remove unused h4_init_debug too.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-h4.c |  130 +---
 1 file changed, 15 insertions(+), 115 deletions(-)

diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 0bbbabe..7926082 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -186,22 +186,24 @@ static struct physmap_flash_data h4_flash_data = {
.nr_parts   = ARRAY_SIZE(h4_partitions),
 };
 
-static struct resource h4_flash_resource = {
-   .flags  = IORESOURCE_MEM,
+static struct gpmc_cs_data h4_gpmc_cs_flash_data = {
+   .cs = H4_FLASH_CS,
+   .mem_size   = SZ_64M,
 };
 
-static struct platform_device h4_flash_device = {
+static struct gpmc_device_pdata h4_gpmc_flash_data = {
.name   = physmap-flash,
.id = 0,
-   .dev= {
-   .platform_data  = h4_flash_data,
-   },
-   .num_resources  = 1,
-   .resource   = h4_flash_resource,
+   .pdata  = h4_flash_data,
+   .pdata_size = sizeof(h4_flash_data),
+   .cs_data= h4_gpmc_cs_flash_data,
+   .num_cs = 1,
 };
 
-static struct platform_device *h4_devices[] __initdata = {
-   h4_flash_device,
+static struct gpmc_device_pdata *gpmc_device_data[1];
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
 };
 
 static struct panel_generic_dpi_data h4_panel_data = {
@@ -226,109 +228,6 @@ static struct omap_dss_board_info h4_dss_data = {
.default_device = h4_lcd_device,
 };
 
-/* 2420 Sysboot setup (2430 is different) */
-static u32 get_sysboot_value(void)
-{
-   return (omap_ctrl_readl(OMAP24XX_CONTROL_STATUS) 
-   (OMAP2_SYSBOOT_5_MASK | OMAP2_SYSBOOT_4_MASK |
-OMAP2_SYSBOOT_3_MASK | OMAP2_SYSBOOT_2_MASK |
-OMAP2_SYSBOOT_1_MASK | OMAP2_SYSBOOT_0_MASK));
-}
-
-/* H4-2420's always used muxed mode, H4-2422's always use non-muxed
- *
- * Note: OMAP-GIT doesn't correctly do is_cpu_omap2422 and is_cpu_omap2423
- *  correctly.  The macro needs to look at production_id not just hawkeye.
- */
-static u32 is_gpmc_muxed(void)
-{
-   u32 mux;
-   mux = get_sysboot_value();
-   if ((mux  0xF) == 0xd)
-   return 1;   /* NAND config (could be either) */
-   if (mux  0x2)  /* if mux'ed */
-   return 1;
-   else
-   return 0;
-}
-
-static inline void __init h4_init_debug(void)
-{
-   int eth_cs;
-   unsigned long cs_mem_base;
-   unsigned int muxed, rate;
-   struct clk *gpmc_fck;
-
-   eth_cs  = H4_SMC91X_CS;
-
-   gpmc_fck = clk_get(NULL, gpmc_fck);   /* Always on ENABLE_ON_INIT */
-   if (IS_ERR(gpmc_fck)) {
-   WARN_ON(1);
-   return;
-   }
-
-   clk_enable(gpmc_fck);
-   rate = clk_get_rate(gpmc_fck);
-   clk_disable(gpmc_fck);
-   clk_put(gpmc_fck);
-
-   if (is_gpmc_muxed())
-   muxed = 0x200;
-   else
-   muxed = 0;
-
-   /* Make sure CS1 timings are correct */
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1,
- 0x00011000 | muxed);
-
-   if (rate = 16000) {
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01);
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803);
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a);
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x04C4);
-   } else if (rate = 13000) {
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x04C4);
-   } else {/* rate = 1 */
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F);
-   gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x03C2);
-   }
-
-   if (gpmc_cs_request(eth_cs, SZ_16M, cs_mem_base)  0) {
-   printk(KERN_ERR Failed to request GPMC mem for smc91x\n);
-   goto out;
-   }
-
-   udelay(100);
-
-   omap_mux_init_gpio(92, 0);
-   if (debug_card_init(cs_mem_base, H4_ETHR_GPIO_IRQ)  0)
-   gpmc_cs_free(eth_cs);
-
-out:
-   clk_disable(gpmc_fck);
-   clk_put

[PATCH 23/39] ARM: OMAP2+: board 3630sdp: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board
code to provide gpmc driver with required information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-3630sdp.c |   23 +++
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/board-3630sdp.c 
b/arch/arm/mach-omap2/board-3630sdp.c
index 143e47f..4e0298a 100644
--- a/arch/arm/mach-omap2/board-3630sdp.c
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -27,18 +27,29 @@
 #include mux.h
 #include sdram-hynix-h8mbx00u0mer-0em.h
 
+static struct gpmc_device_pdata *gpmc_device_data[4];
+static struct gpmc_device_pdata **gpmc_cur = gpmc_device_data;
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
+};
+
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
 
 static struct omap_smc91x_platform_data board_smc91x_data = {
.cs = 3,
.flags  = GPMC_MUX_ADD_DATA | IORESOURCE_IRQ_LOWLEVEL,
.skip_timing= true,
+   .gpio_irq   = 158,
 };
 
 static void __init board_smc91x_init(void)
 {
-   board_smc91x_data.gpio_irq = 158;
-   gpmc_smc91x_init(board_smc91x_data);
+   *gpmc_cur = gpmc_smc91x_init(board_smc91x_data);
+   if (*gpmc_cur)
+   gpmc_data.num_device++, gpmc_cur++;
+   else
+   pr_err(error: unable to initilaize gpmc smsc911x\n);
 }
 
 #else
@@ -204,9 +215,13 @@ static void __init omap_sdp_init(void)
omap_sdrc_init(h8mbx00u0mer0em_sdrc_params,
  h8mbx00u0mer0em_sdrc_params);
zoom_display_init();
+
board_smc91x_init();
-   board_flash_init(sdp_flash_partitions, chip_sel_sdp,
-   NAND_BUSWIDTH_16, NULL);
+   gpmc_data.num_device += board_flash_init(sdp_flash_partitions,
+   chip_sel_sdp, NAND_BUSWIDTH_16,
+   gpmc_cur) - gpmc_cur;
+   omap_init_gpmc(gpmc_data);
+
enable_board_wakeup_source();
usbhs_init(usbhs_bdata);
 }
-- 
1.7.10

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


[PATCH 24/39] ARM: OMAP2+: board 3430sdp: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board
code to provide gpmc driver with required information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-3430sdp.c |   17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/board-3430sdp.c 
b/arch/arm/mach-omap2/board-3430sdp.c
index 367a466..cea5ca5 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -59,6 +59,12 @@
 
 #define TWL4030_MSECURE_GPIO 22
 
+static struct gpmc_device_pdata *gpmc_device_data[4];
+static struct gpmc_device_pdata **gpmc_cur = gpmc_device_data;
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
+};
 static uint32_t board_keymap[] = {
KEY(0, 0, KEY_LEFT),
KEY(0, 1, KEY_RIGHT),
@@ -444,7 +450,11 @@ static void __init board_smc91x_init(void)
else
board_smc91x_data.gpio_irq = 29;
 
-   gpmc_smc91x_init(board_smc91x_data);
+   *gpmc_cur = gpmc_smc91x_init(board_smc91x_data);
+   if (*gpmc_cur)
+   gpmc_data.num_device++, gpmc_cur++;
+   else
+   pr_err(error: unable to initilaize gpmc smsc911x\n);
 }
 
 #else
@@ -621,7 +631,10 @@ static void __init omap_3430sdp_init(void)
omap_sdrc_init(hyb18m512160af6_sdrc_params, NULL);
usb_musb_init(NULL);
board_smc91x_init();
-   board_flash_init(sdp_flash_partitions, chip_sel_3430, 0, NULL);
+   gpmc_data.num_device += board_flash_init(sdp_flash_partitions,
+   chip_sel_3430, 0, gpmc_cur) - gpmc_cur;
+   omap_init_gpmc(gpmc_data);
+
sdp3430_display_init();
enable_board_wakeup_source();
usbhs_init(usbhs_bdata);
-- 
1.7.10

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


[PATCH 25/39] ARM: OMAP2+: board 2430sdp: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board
code to provide gpmc driver with required information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-2430sdp.c |   42 +--
 1 file changed, 25 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-omap2/board-2430sdp.c 
b/arch/arm/mach-omap2/board-2430sdp.c
index 68679a8..d94ada4 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -46,9 +46,16 @@
 #include hsmmc.h
 #include common-board-devices.h
 
-#define SDP2430_CS0_BASE   0x0400
+#define SDP2430_FLASH_CS   0
 #define SECONDARY_LCD_GPIO 147
 
+static struct gpmc_device_pdata *gpmc_device_data[2];
+static struct gpmc_device_pdata **gpmc_cur = gpmc_device_data;
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
+};
+
 static struct mtd_partition sdp2430_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */
{
@@ -86,24 +93,18 @@ static struct physmap_flash_data sdp2430_flash_data = {
.nr_parts   = ARRAY_SIZE(sdp2430_partitions),
 };
 
-static struct resource sdp2430_flash_resource = {
-   .start  = SDP2430_CS0_BASE,
-   .end= SDP2430_CS0_BASE + SZ_64M - 1,
-   .flags  = IORESOURCE_MEM,
+static struct gpmc_cs_data sdp2430_gpmc_cs_flash_data = {
+   .cs = SDP2430_FLASH_CS,
+   .mem_size   = SZ_64M,
 };
 
-static struct platform_device sdp2430_flash_device = {
+static struct gpmc_device_pdata sdp2430_gpmc_flash_device = {
.name   = physmap-flash,
.id = 0,
-   .dev = {
-   .platform_data  = sdp2430_flash_data,
-   },
-   .num_resources  = 1,
-   .resource   = sdp2430_flash_resource,
-};
-
-static struct platform_device *sdp2430_devices[] __initdata = {
-   sdp2430_flash_device,
+   .pdata  = sdp2430_flash_data,
+   .pdata_size = sizeof(sdp2430_flash_data),
+   .cs_data= sdp2430_gpmc_cs_flash_data,
+   .num_cs = 1,
 };
 
 /* LCD */
@@ -181,7 +182,11 @@ static struct omap_smc91x_platform_data board_smc91x_data 
= {
 static void __init board_smc91x_init(void)
 {
omap_mux_init_gpio(149, OMAP_PIN_INPUT);
-   gpmc_smc91x_init(board_smc91x_data);
+   *gpmc_cur = gpmc_smc91x_init(board_smc91x_data);
+   if (*gpmc_cur)
+   gpmc_data.num_device++, gpmc_cur++;
+   else
+   pr_err(error: unable to initilaize gpmc smsc911x\n);
 }
 
 #else
@@ -276,7 +281,9 @@ static void __init omap_2430sdp_init(void)
 
omap2430_i2c_init();
 
-   platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
+   *gpmc_cur++ = sdp2430_gpmc_flash_device;
+   gpmc_data.num_device++;
+
omap_serial_init();
omap_sdrc_init(NULL, NULL);
omap_hsmmc_init(mmc);
@@ -286,6 +293,7 @@ static void __init omap_2430sdp_init(void)
usb_musb_init(NULL);
 
board_smc91x_init();
+   omap_init_gpmc(gpmc_data);
 
/* Turn off secondary LCD backlight */
gpio_request_one(SECONDARY_LCD_GPIO, GPIOF_OUT_INIT_LOW,
-- 
1.7.10

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


[PATCH 26/39] ARM: OMAP2+: board cm-t3517: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board
code to provide gpmc driver with required information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-cm-t3517.c |   10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/board-cm-t3517.c 
b/arch/arm/mach-omap2/board-cm-t3517.c
index 9e66e16..6aa6b4a 100644
--- a/arch/arm/mach-omap2/board-cm-t3517.c
+++ b/arch/arm/mach-omap2/board-cm-t3517.c
@@ -234,6 +234,11 @@ static struct mtd_partition cm_t3517_nand_partitions[] = {
},
 };
 
+static struct gpmc_device_pdata *gpmc_device_data[1];
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
+};
 static struct omap_nand_platform_data cm_t3517_nand_data = {
.parts  = cm_t3517_nand_partitions,
.nr_parts   = ARRAY_SIZE(cm_t3517_nand_partitions),
@@ -242,8 +247,8 @@ static struct omap_nand_platform_data cm_t3517_nand_data = {
 
 static void __init cm_t3517_init_nand(void)
 {
-   if (gpmc_nand_init(cm_t3517_nand_data)  0)
-   pr_err(CM-T3517: NAND initialization failed\n);
+   *gpmc_device_data = gpmc_nand_init(cm_t3517_nand_data);
+   gpmc_data.num_device++;
 }
 #else
 static inline void cm_t3517_init_nand(void) {}
@@ -289,6 +294,7 @@ static void __init cm_t3517_init(void)
omap_board_config_size = ARRAY_SIZE(cm_t3517_config);
cm_t3517_init_leds();
cm_t3517_init_nand();
+   omap_init_gpmc(gpmc_data);
cm_t3517_init_rtc();
cm_t3517_init_usbh();
cm_t3517_init_hecc();
-- 
1.7.10

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


[PATCH 27/39] ARM: OMAP2+: board cm-t35: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board
code to provide gpmc driver with required information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-cm-t35.c |   21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/board-cm-t35.c 
b/arch/arm/mach-omap2/board-cm-t35.c
index 909a8b9..5b0b637 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -66,6 +66,13 @@
 #include linux/smsc911x.h
 #include plat/gpmc-smsc911x.h
 
+static struct gpmc_device_pdata *gpmc_device_data[2];
+static struct gpmc_device_pdata **gpmc_cur = gpmc_device_data;
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
+};
+
 static struct omap_smsc911x_platform_data cm_t35_smsc911x_cfg = {
.id = 0,
.cs = CM_T35_SMSC911X_CS,
@@ -99,8 +106,17 @@ static void __init cm_t35_init_ethernet(void)
regulator_register_fixed(1, sb_t35_smsc911x_supplies,
 ARRAY_SIZE(sb_t35_smsc911x_supplies));
 
-   gpmc_smsc911x_init(cm_t35_smsc911x_cfg);
-   gpmc_smsc911x_init(sb_t35_smsc911x_cfg);
+   *gpmc_cur = gpmc_smsc911x_init(cm_t35_smsc911x_cfg);
+   if (*gpmc_cur)
+   gpmc_data.num_device++, gpmc_cur++;
+   else
+   pr_err(error: initilaizing gpmc smsc911x instance 1\n);
+
+   *gpmc_cur = gpmc_smsc911x_init(sb_t35_smsc911x_cfg);
+   if (*gpmc_cur)
+   gpmc_data.num_device++, gpmc_cur++;
+   else
+   pr_err(error: initilaizing gpmc smsc911x instance 2\n);
 }
 #else
 static inline void __init cm_t35_init_ethernet(void) { return; }
@@ -658,6 +674,7 @@ static void __init cm_t3x_common_init(void)
cm_t35_init_i2c();
omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
cm_t35_init_ethernet();
+   omap_init_gpmc(gpmc_data);
cm_t35_init_led();
cm_t35_init_display();
 
-- 
1.7.10

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


[PATCH 28/39] ARM: OMAP2+: board ldp: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board
code to provide gpmc driver with required information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-ldp.c |   26 +++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index b76f28d..1ebc024 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -43,6 +43,7 @@
 #include asm/delay.h
 #include plat/usb.h
 #include plat/gpmc-smsc911x.h
+#include plat/nand.h
 
 #include video/omapdss.h
 #include video/omap-panel-generic-dpi.h
@@ -58,6 +59,13 @@
 #define DEBUG_BASE 0x0800
 #define LDP_ETHR_START DEBUG_BASE
 
+static struct gpmc_device_pdata *gpmc_device_data[2];
+static struct gpmc_device_pdata **gpmc_cur = gpmc_device_data;
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
+};
+
 static uint32_t board_keymap[] = {
KEY(0, 0, KEY_1),
KEY(1, 0, KEY_2),
@@ -180,7 +188,9 @@ static struct omap_smsc911x_platform_data smsc911x_cfg = {
 
 static inline void __init ldp_init_smsc911x(void)
 {
-   gpmc_smsc911x_init(smsc911x_cfg);
+   *gpmc_cur = gpmc_smsc911x_init(smsc911x_cfg);
+   if (*gpmc_cur)
+   gpmc_data.num_device++, gpmc_cur++;
 }
 
 /* LCD */
@@ -418,6 +428,8 @@ static struct regulator_consumer_supply dummy_supplies[] = {
 
 static void __init omap_ldp_init(void)
 {
+   struct omap_nand_platform_data *nand_data;
+
regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
ldp_init_smsc911x();
@@ -427,8 +439,16 @@ static void __init omap_ldp_init(void)
omap_serial_init();
omap_sdrc_init(NULL, NULL);
usb_musb_init(NULL);
-   board_nand_init(ldp_nand_partitions, ARRAY_SIZE(ldp_nand_partitions),
-   ZOOM_NAND_CS, 0, nand_default_timings);
+
+   nand_data = board_nand_init(ldp_nand_partitions,
+   ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS,
+   0, nand_default_timings);
+   if (nand_data != NULL) {
+   *gpmc_cur++ = gpmc_nand_init(nand_data);
+   gpmc_data.num_device++;
+   }
+
+   omap_init_gpmc(gpmc_data);
 
omap_hsmmc_init(mmc);
ldp_display_init();
-- 
1.7.10

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


[PATCH 29/39] ARM: OMAP2+: board n8x0: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board
code to provide gpmc driver with required information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-n8x0.c |   18 +++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index 94f6077..d3d866a 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -36,6 +36,7 @@
 #include plat/onenand.h
 #include plat/mmc.h
 #include plat/serial.h
+#include plat/gpmc.h
 
 #include mux.h
 
@@ -45,6 +46,13 @@
 #define TUSB6010_GPIO_ENABLE   0
 #define TUSB6010_DMACHAN   0x3f
 
+static struct gpmc_device_pdata *gpmc_device_data[2];
+static struct gpmc_device_pdata **gpmc_cur = gpmc_device_data;
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
+};
+
 #if defined(CONFIG_USB_MUSB_TUSB6010) || 
defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
 /*
  * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and
@@ -114,10 +122,12 @@ static void __init n8x0_usb_init(void)
}
tusb_set_power(0);
 
-   ret = tusb6010_setup_interface(tusb_data, TUSB6010_REFCLK_19, 2,
+   *gpmc_cur = tusb6010_setup_interface(tusb_data, TUSB6010_REFCLK_19, 2,
TUSB6010_ASYNC_CS, TUSB6010_SYNC_CS,
TUSB6010_GPIO_INT, TUSB6010_DMACHAN);
-   if (ret != 0)
+   if (*gpmc_cur)
+   gpmc_data.num_device++, gpmc_cur++;
+   else
goto err;
 
printk(announce);
@@ -785,7 +795,9 @@ static void __init n8x0_init_machine(void)
ARRAY_SIZE(n810_i2c_board_info_2));
board_serial_init();
omap_sdrc_init(NULL, NULL);
-   gpmc_onenand_init(board_onenand_data);
+   *gpmc_cur++ = gpmc_onenand_init(board_onenand_data);
+   gpmc_data.num_device++;
+   omap_init_gpmc(gpmc_data);
n8x0_mmc_init();
n8x0_usb_init();
 }
-- 
1.7.10

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


[PATCH 30/39] ARM: OMAP2+: board omap3logic: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board
code to provide gpmc driver with required information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-omap3logic.c |   13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/board-omap3logic.c 
b/arch/arm/mach-omap2/board-omap3logic.c
index 9b3c141..9867fc8 100644
--- a/arch/arm/mach-omap2/board-omap3logic.c
+++ b/arch/arm/mach-omap2/board-omap3logic.c
@@ -55,6 +55,12 @@
 #define OMAP3_TORPEDO_MMC_GPIO_CD  127
 #define OMAP3_TORPEDO_SMSC911X_GPIO_IRQ129
 
+static struct gpmc_device_pdata *gpmc_device_data[1];
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
+};
+
 static struct regulator_consumer_supply omap3logic_vmmc1_supply[] = {
REGULATOR_SUPPLY(vmmc, omap_hsmmc.0),
 };
@@ -180,7 +186,11 @@ static inline void __init board_smsc911x_init(void)
return;
}
 
-   gpmc_smsc911x_init(board_smsc911x_data);
+   *gpmc_device_data = gpmc_smsc911x_init(board_smsc911x_data);
+   if (*gpmc_device_data)
+   gpmc_data.num_device++;
+   else
+   pr_err(error: unable to initilaize gpmc smsc911x\n);
 }
 
 #ifdef CONFIG_OMAP_MUX
@@ -204,6 +214,7 @@ static void __init omap3logic_init(void)
omap_sdrc_init(NULL, NULL);
board_mmc_init();
board_smsc911x_init();
+   omap_init_gpmc(gpmc_data);
 
/* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal(sdrc_cke0, OMAP_PIN_OUTPUT);
-- 
1.7.10

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


[PATCH 31/39] ARM: OMAP2+: board omap3pandora: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board
code to provide gpmc driver with required information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-omap3pandora.c |   11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3pandora.c 
b/arch/arm/mach-omap2/board-omap3pandora.c
index 33d995d..25b2de6 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -57,6 +57,12 @@
 #define PANDORA_WIFI_NRESET_GPIO   23
 #define OMAP3_PANDORA_TS_GPIO  94
 
+static struct gpmc_device_pdata *gpmc_device_data[1];
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
+};
+
 static struct mtd_partition omap3pandora_nand_partitions[] = {
{
.name   = xloader,
@@ -607,8 +613,9 @@ static void __init omap3pandora_init(void)
omap_ads7846_init(1, OMAP3_PANDORA_TS_GPIO, 0, NULL);
usbhs_init(usbhs_bdata);
usb_musb_init(NULL);
-   gpmc_nand_init(pandora_nand_data);
-
+   *gpmc_device_data = gpmc_nand_init(pandora_nand_data);
+   gpmc_data.num_device++;
+   omap_init_gpmc(gpmc_data);
/* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal(sdrc_cke0, OMAP_PIN_OUTPUT);
omap_mux_init_signal(sdrc_cke1, OMAP_PIN_OUTPUT);
-- 
1.7.10

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


[PATCH 32/39] ARM: OMAP2+: board omap3stalker: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board
code to provide gpmc driver with required information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-omap3stalker.c |   13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/board-omap3stalker.c 
b/arch/arm/mach-omap2/board-omap3stalker.c
index 4dffc95..5e92d54 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -56,6 +56,12 @@
 #include hsmmc.h
 #include common-board-devices.h
 
+static struct gpmc_device_pdata *gpmc_device_data[1];
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
+};
+
 #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
 #include plat/gpmc-smsc911x.h
 
@@ -74,7 +80,11 @@ static struct omap_smsc911x_platform_data smsc911x_cfg = {
 static inline void __init omap3stalker_init_eth(void)
 {
omap_mux_init_gpio(19, OMAP_PIN_INPUT_PULLUP);
-   gpmc_smsc911x_init(smsc911x_cfg);
+   *gpmc_device_data = gpmc_smsc911x_init(smsc911x_cfg);
+   if (*gpmc_device_data)
+   gpmc_data.num_device++;
+   else
+   pr_err(error: unable to initilaize gpmc smsc911x\n);
 }
 
 #else
@@ -443,6 +453,7 @@ static void __init omap3_stalker_init(void)
omap_mux_init_gpio(18, OMAP_PIN_INPUT_PULLUP);
 
omap3stalker_init_eth();
+   omap_init_gpmc(gpmc_data);
omap3_stalker_display_init();
 /* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal(sdr_cke0, OMAP_PIN_OUTPUT);
-- 
1.7.10

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


[PATCH 33/39] ARM: OMAP2+: board omap4pcm049: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board
code to provide gpmc driver with required information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-omap4pcm049.c |   13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/board-omap4pcm049.c 
b/arch/arm/mach-omap2/board-omap4pcm049.c
index 81de7d5..b4ead86 100644
--- a/arch/arm/mach-omap2/board-omap4pcm049.c
+++ b/arch/arm/mach-omap2/board-omap4pcm049.c
@@ -130,6 +130,12 @@ static struct omap2_hsmmc_info mmc[] = {
}, {}   /* Terminator */
 };
 
+static struct gpmc_device_pdata *gpmc_device_data[1];
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
+};
+
 #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
 static struct regulator_consumer_supply dummy_supplies[] = {
REGULATOR_SUPPLY(vddvario, smsc911x.0),
@@ -147,7 +153,11 @@ static inline void __init pcm049_init_smsc911x(void)
 {
omap_mux_init_gpio(OMAP4_PCM049_ETH_GPIO_IRQ, OMAP_PIN_INPUT);
regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
-   gpmc_smsc911x_init(board_smsc911x_data);
+   *gpmc_device_data = gpmc_smsc911x_init(board_smsc911x_data);
+   if (*gpmc_device_data)
+   gpmc_data.num_device++;
+   else
+   pr_err(error: unable to initilaize gpmc smsc911x\n);
 }
 #else
 static inline void __init pcm049_init_smsc911x(void) { return; }
@@ -562,6 +572,7 @@ static void __init pcm049_init(void)
pm_power_off = pcm049_power_off;
omap4_mux_init(board_mux, NULL, OMAP_PACKAGE_CBS);
pcm049_init_smsc911x();
+   omap_init_gpmc(gpmc_data);
pcm049_i2c_init();
platform_add_devices(pcm049_devices, ARRAY_SIZE(pcm049_devices));
board_serial_init();
-- 
1.7.10

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


[PATCH 34/39] ARM: OMAP2+: board overo: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board
code to provide gpmc driver with required information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-overo.c |   29 ++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/board-overo.c 
b/arch/arm/mach-omap2/board-overo.c
index e08479a..fa0197e 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -72,6 +72,13 @@
 #define OVERO_SMSC911X2_CS 4
 #define OVERO_SMSC911X2_GPIO   65
 
+static struct gpmc_device_pdata *gpmc_device_data[3];
+static struct gpmc_device_pdata **gpmc_cur = gpmc_device_data;
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
+};
+
 #if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
 
@@ -137,8 +144,16 @@ static struct omap_smsc911x_platform_data smsc911x2_cfg = {
 
 static void __init overo_init_smsc911x(void)
 {
-   gpmc_smsc911x_init(smsc911x_cfg);
-   gpmc_smsc911x_init(smsc911x2_cfg);
+   *gpmc_cur = gpmc_smsc911x_init(smsc911x_cfg);
+   if (*gpmc_cur)
+   gpmc_data.num_device++, gpmc_cur++;
+   else
+   pr_err(error: %s: smsc911x instance 1 setup\n, __func__);
+   *gpmc_cur = gpmc_smsc911x_init(smsc911x2_cfg);
+   if (*gpmc_cur)
+   gpmc_data.num_device++, gpmc_cur++;
+   else
+   pr_err(error: %s: smsc911x instance 1 setup\n, __func__);
 }
 
 #else
@@ -509,6 +524,7 @@ static struct regulator_consumer_supply dummy_supplies[] = {
 static void __init overo_init(void)
 {
int ret;
+   struct omap_nand_platform_data *nand_data;
 
regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
@@ -518,12 +534,19 @@ static void __init overo_init(void)
omap_serial_init();
omap_sdrc_init(mt46h32m32lf6_sdrc_params,
  mt46h32m32lf6_sdrc_params);
-   board_nand_init(overo_nand_partitions,
+
+   nand_data = board_nand_init(overo_nand_partitions,
ARRAY_SIZE(overo_nand_partitions), GPMC_CS_NUM, 0, NULL);
+   if (nand_data != NULL) {
+   *gpmc_cur++ = gpmc_nand_init(nand_data);
+   gpmc_data.num_device++;
+   }
+
usb_musb_init(NULL);
usbhs_init(usbhs_bdata);
overo_spi_init();
overo_init_smsc911x();
+   omap_init_gpmc(gpmc_data);
overo_display_init();
overo_init_led();
overo_init_keys();
-- 
1.7.10

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


[PATCH 35/39] ARM: OMAP2+: board rm680: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board
code to provide gpmc driver with required information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-rm680.c |   10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/board-rm680.c 
b/arch/arm/mach-omap2/board-rm680.c
index ae53d71..e28e606 100644
--- a/arch/arm/mach-omap2/board-rm680.c
+++ b/arch/arm/mach-omap2/board-rm680.c
@@ -33,6 +33,12 @@
 #include sdram-nokia.h
 #include common-board-devices.h
 
+static struct gpmc_device_pdata *gpmc_device_data[1];
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
+};
+
 static struct regulator_consumer_supply rm680_vemmc_consumers[] = {
REGULATOR_SUPPLY(vmmc, omap_hsmmc.1),
 };
@@ -119,7 +125,8 @@ static void __init rm680_peripherals_init(void)
platform_add_devices(rm680_peripherals_devices,
ARRAY_SIZE(rm680_peripherals_devices));
rm680_i2c_init();
-   gpmc_onenand_init(board_onenand_data);
+   *gpmc_device_data = gpmc_onenand_init(board_onenand_data);
+   gpmc_data.num_device++;
omap_hsmmc_init(mmc);
 }
 
@@ -141,6 +148,7 @@ static void __init rm680_init(void)
 
usb_musb_init(NULL);
rm680_peripherals_init();
+   omap_init_gpmc(gpmc_data);
 }
 
 MACHINE_START(NOKIA_RM680, Nokia RM-680 board)
-- 
1.7.10

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


[PATCH 36/39] ARM: OMAP2+: board rx51: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board
code to provide gpmc driver with required information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-rx51-peripherals.c |   17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c 
b/arch/arm/mach-omap2/board-rx51-peripherals.c
index ae957c9..af7909e 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -73,6 +73,13 @@ enum {
 static struct wl12xx_platform_data wl1251_pdata;
 static struct tsc2005_platform_data tsc2005_pdata;
 
+static struct gpmc_device_pdata *gpmc_device_data[2];
+static struct gpmc_device_pdata **gpmc_cur = gpmc_device_data;
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
+};
+
 #if defined(CONFIG_SENSORS_TSL2563) || defined(CONFIG_SENSORS_TSL2563_MODULE)
 static struct tsl2563_platform_data rx51_tsl2563_platform_data = {
.cover_comp_gain = 16,
@@ -1039,7 +1046,11 @@ static void __init board_smc91x_init(void)
omap_mux_init_gpio(86, OMAP_PIN_OUTPUT);
omap_mux_init_gpio(164, OMAP_PIN_OUTPUT);
 
-   gpmc_smc91x_init(board_smc91x_data);
+   *gpmc_cur = gpmc_smc91x_init(board_smc91x_data);
+   if (*gpmc_cur)
+   gpmc_data.num_device++, gpmc_cur++;
+   else
+   pr_err(error: gpmc smsc911x setup\n);
 }
 
 #else
@@ -1136,8 +1147,10 @@ void __init rx51_peripherals_init(void)
 {
rx51_i2c_init();
regulator_has_full_constraints();
-   gpmc_onenand_init(board_onenand_data);
+   *gpmc_cur++ = gpmc_onenand_init(board_onenand_data);
+   gpmc_data.num_device++;
board_smc91x_init();
+   omap_init_gpmc(gpmc_data);
rx51_add_gpio_keys();
rx51_init_wl1251();
rx51_init_tsc2005();
-- 
1.7.10

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


[PATCH 37/39] ARM: OMAP2+: board zoom-debugboard: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board
code to provide gpmc driver with required information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-zoom-debugboard.c |   47 +++
 1 file changed, 27 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-omap2/board-zoom-debugboard.c 
b/arch/arm/mach-omap2/board-zoom-debugboard.c
index f64f441..dae7df2 100644
--- a/arch/arm/mach-omap2/board-zoom-debugboard.c
+++ b/arch/arm/mach-omap2/board-zoom-debugboard.c
@@ -31,6 +31,13 @@
 #define DEBUG_BASE 0x0800
 #define ZOOM_ETHR_STARTDEBUG_BASE
 
+static struct gpmc_device_pdata *gpmc_device_data[2];
+static struct gpmc_device_pdata **gpmc_cur = gpmc_device_data;
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
+};
+
 static struct omap_smsc911x_platform_data zoom_smsc911x_cfg = {
.cs = ZOOM_SMSC911X_CS,
.gpio_irq   = ZOOM_SMSC911X_GPIO,
@@ -40,7 +47,11 @@ static struct omap_smsc911x_platform_data zoom_smsc911x_cfg 
= {
 
 static inline void __init zoom_init_smsc911x(void)
 {
-   gpmc_smsc911x_init(zoom_smsc911x_cfg);
+   *gpmc_cur = gpmc_smsc911x_init(zoom_smsc911x_cfg);
+   if (*gpmc_cur)
+   gpmc_data.num_device++, gpmc_cur++;
+   else
+   pr_err(error: %s: gpmc smsc911x setup\n, __func__);
 }
 
 static struct plat_serial8250_port serial_platform_data[] = {
@@ -56,18 +67,22 @@ static struct plat_serial8250_port serial_platform_data[] = 
{
}
 };
 
-static struct platform_device zoom_debugboard_serial_device = {
+static struct gpmc_cs_data zoom_debugboard_gpmc_cs_serial_data = {
+   .cs = ZOOM_QUADUART_CS,
+   .mem_size   = SZ_1M,
+};
+
+static struct gpmc_device_pdata zoom_debugboard_gpmc_serial_data = {
.name   = serial8250,
.id = PLAT8250_DEV_PLATFORM,
-   .dev= {
-   .platform_data  = serial_platform_data,
-   },
+   .pdata  = serial_platform_data,
+   .pdata_size = sizeof(serial_platform_data),
+   .cs_data= zoom_debugboard_gpmc_cs_serial_data,
+   .num_cs = 1,
 };
 
 static inline void __init zoom_init_quaduart(void)
 {
-   int quart_cs;
-   unsigned long cs_mem_base;
int quart_gpio = 0;
 
if (gpio_request_one(ZOOM_QUADUART_RST_GPIO,
@@ -78,14 +93,6 @@ static inline void __init zoom_init_quaduart(void)
return;
}
 
-   quart_cs = ZOOM_QUADUART_CS;
-
-   if (gpmc_cs_request(quart_cs, SZ_1M, cs_mem_base)  0) {
-   printk(KERN_ERR Failed to request GPMC mem
-   for Quad UART(TL16CP754C)\n);
-   return;
-   }
-
quart_gpio = ZOOM_QUADUART_GPIO;
 
if (gpio_request_one(quart_gpio, GPIOF_IN, TL16CP754C GPIO)  0)
@@ -93,6 +100,9 @@ static inline void __init zoom_init_quaduart(void)
quart_gpio);
 
serial_platform_data[0].irq = gpio_to_irq(102);
+
+   *gpmc_cur++ = zoom_debugboard_gpmc_serial_data;
+   gpmc_data.num_device++;
 }
 
 static inline int omap_zoom_debugboard_detect(void)
@@ -116,10 +126,6 @@ static inline int omap_zoom_debugboard_detect(void)
return ret;
 }
 
-static struct platform_device *zoom_devices[] __initdata = {
-   zoom_debugboard_serial_device,
-};
-
 static struct regulator_consumer_supply dummy_supplies[] = {
REGULATOR_SUPPLY(vddvario, smsc911x.0),
REGULATOR_SUPPLY(vdd33a, smsc911x.0),
@@ -133,5 +139,6 @@ int __init zoom_debugboard_init(void)
regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
zoom_init_smsc911x();
zoom_init_quaduart();
-   return platform_add_devices(zoom_devices, ARRAY_SIZE(zoom_devices));
+   omap_init_gpmc(gpmc_data);
+   return 0;
 }
-- 
1.7.10

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


[PATCH 38/39] OMAP3: igep0020: Add support for Micron NAND Flash storage memory

2012-05-01 Thread Afzal Mohammed
From: Javier Martinez Canillas jav...@dowhile0.org

IGEP-based boards can have two different flash memories, a OneNAND or
a NAND device. The boot configuration pins (sys_boot) are used to
specify which memory is available.

Also, this patch removes unnecesary code for registering the OneNAND.

af...@ti.com: Update to use modified board_nand_init

Signed-off-by: Javier Martinez Canillas jav...@dowhile0.org
Signed-off-by: Afzal Mohammed af...@ti.com

fixup: igep
---
 arch/arm/mach-omap2/board-igep0020.c |   75 ++
 1 file changed, 31 insertions(+), 44 deletions(-)

diff --git a/arch/arm/mach-omap2/board-igep0020.c 
b/arch/arm/mach-omap2/board-igep0020.c
index 930c0d3..6d171ca 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -24,6 +24,8 @@
 #include linux/i2c/twl.h
 #include linux/mmc/host.h
 
+#include linux/mtd/nand.h
+
 #include asm/mach-types.h
 #include asm/mach/arch.h
 
@@ -39,6 +41,8 @@
 #include hsmmc.h
 #include sdram-numonyx-m65kam.h
 #include common-board-devices.h
+#include board-flash.h
+#include control.h
 
 #define IGEP2_SMSC911X_CS   5
 #define IGEP2_SMSC911X_GPIO 176
@@ -60,6 +64,10 @@
 #define IGEP3_GPIO_LED1_RED16
 #define IGEP3_GPIO_USBH_NRESET  183
 
+#define IGEP_SYSBOOT_MASK   0x1f
+#define IGEP_SYSBOOT_NAND   0x0f
+#define IGEP_SYSBOOT_ONENAND0x10
+
 /*
  * IGEP2 Hardware Revision Table
  *
@@ -110,8 +118,10 @@ static void __init igep2_get_revision(void)
gpio_free(IGEP2_GPIO_LED1_RED);
 }
 
-#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
-   defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+#if defined(CONFIG_MTD_ONENAND_OMAP2) ||   \
+   defined(CONFIG_MTD_ONENAND_OMAP2_MODULE) || \
+   defined(CONFIG_MTD_NAND_OMAP2) ||   \
+   defined(CONFIG_MTD_NAND_OMAP2_MODULE)
 
 #define ONENAND_MAP 0x2000
 
@@ -123,7 +133,7 @@ static void __init igep2_get_revision(void)
  * So MTD regards it as 4KiB page size and 256KiB block size 64*(2*2048)
  */
 
-static struct mtd_partition igep_onenand_partitions[] = {
+static struct mtd_partition igep_flash_partitions[] = {
{
.name   = X-Loader,
.offset = 0,
@@ -151,50 +161,27 @@ static struct mtd_partition igep_onenand_partitions[] = {
},
 };
 
-static struct omap_onenand_platform_data igep_onenand_data = {
-   .parts = igep_onenand_partitions,
-   .nr_parts = ARRAY_SIZE(igep_onenand_partitions),
-   .dma_channel= -1,   /* disable DMA in OMAP OneNAND driver */
-};
-
-static struct platform_device igep_onenand_device = {
-   .name   = omap2-onenand,
-   .id = -1,
-   .dev = {
-   .platform_data = igep_onenand_data,
-   },
-};
+static inline u32 igep_get_sysboot_value(void)
+{
+   return omap_ctrl_readl(OMAP343X_CONTROL_STATUS)  IGEP_SYSBOOT_MASK;
+}
 
 static void __init igep_flash_init(void)
 {
-   u8 cs = 0;
-   u8 onenandcs = GPMC_CS_NUM + 1;
-
-   for (cs = 0; cs  GPMC_CS_NUM; cs++) {
-   u32 ret;
-   ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
-
-   /* Check if NAND/oneNAND is configured */
-   if ((ret  0xC00) == 0x800)
-   /* NAND found */
-   pr_err(IGEP: Unsupported NAND found\n);
-   else {
-   ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
-   if ((ret  0x3F) == (ONENAND_MAP  24))
-   /* ONENAND found */
-   onenandcs = cs;
-   }
-   }
-
-   if (onenandcs  GPMC_CS_NUM) {
-   pr_err(IGEP: Unable to find configuration in GPMC\n);
-   return;
-   }
-
-   igep_onenand_data.cs = onenandcs;
-
-   if (platform_device_register(igep_onenand_device)  0)
-   pr_err(IGEP: Unable to register OneNAND device\n);
+   u32 mux;
+   mux = igep_get_sysboot_value();
+
+   if (mux == IGEP_SYSBOOT_NAND) {
+   pr_info(IGEP: initializing NAND memory device\n);
+   board_nand_init(igep_flash_partitions,
+   ARRAY_SIZE(igep_flash_partitions),
+   0, NAND_BUSWIDTH_16, NULL);
+   } else if (mux == IGEP_SYSBOOT_ONENAND) {
+   pr_info(IGEP: initializing OneNAND memory device\n);
+   board_onenand_init(igep_flash_partitions,
+  ARRAY_SIZE(igep_flash_partitions), 0);
+   } else
+   pr_err(IGEP: Flash: unsupported sysboot sequence found\n);
 }
 
 #else
-- 
1.7.10

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


[PATCH 39/39] ARM: OMAP2+: board igep0020: gpmc driver adaptation

2012-05-01 Thread Afzal Mohammed
gpmc code has been converted to driver. Modify the board
code to provide gpmc driver with required information.

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/board-igep0020.c |   32 
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/board-igep0020.c 
b/arch/arm/mach-omap2/board-igep0020.c
index 6d171ca..91de8ce 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -36,6 +36,7 @@
 #include video/omapdss.h
 #include video/omap-panel-dvi.h
 #include plat/onenand.h
+#include plat/nand.h
 
 #include mux.h
 #include hsmmc.h
@@ -118,6 +119,13 @@ static void __init igep2_get_revision(void)
gpio_free(IGEP2_GPIO_LED1_RED);
 }
 
+static struct gpmc_device_pdata *gpmc_device_data[2];
+static struct gpmc_device_pdata **gpmc_cur = gpmc_device_data;
+
+static struct gpmc_pdata gpmc_data = {
+   .device_pdata = gpmc_device_data,
+};
+
 #if defined(CONFIG_MTD_ONENAND_OMAP2) ||   \
defined(CONFIG_MTD_ONENAND_OMAP2_MODULE) || \
defined(CONFIG_MTD_NAND_OMAP2) ||   \
@@ -172,14 +180,26 @@ static void __init igep_flash_init(void)
mux = igep_get_sysboot_value();
 
if (mux == IGEP_SYSBOOT_NAND) {
+   struct omap_nand_platform_data *nand_data;
+
pr_info(IGEP: initializing NAND memory device\n);
-   board_nand_init(igep_flash_partitions,
+   nand_data = board_nand_init(igep_flash_partitions,
ARRAY_SIZE(igep_flash_partitions),
-   0, NAND_BUSWIDTH_16, NULL);
+   0, NAND_BUSWIDTH_16, nand_default_timings);
+   if (nand_data != NULL) {
+   *gpmc_cur++ = gpmc_nand_init(nand_data);
+   gpmc_data.num_device++;
+   }
} else if (mux == IGEP_SYSBOOT_ONENAND) {
+   struct omap_onenand_platform_data *onenand_data;
+
pr_info(IGEP: initializing OneNAND memory device\n);
-   board_onenand_init(igep_flash_partitions,
+   onenand_data = board_onenand_init(igep_flash_partitions,
   ARRAY_SIZE(igep_flash_partitions), 0);
+   if (onenand_data != NULL) {
+   *gpmc_cur++ = gpmc_onenand_init(onenand_data);
+   gpmc_data.num_device++;
+   }
} else
pr_err(IGEP: Flash: unsupported sysboot sequence found\n);
 }
@@ -202,7 +222,11 @@ static struct omap_smsc911x_platform_data smsc911x_cfg = {
 
 static inline void __init igep2_init_smsc911x(void)
 {
-   gpmc_smsc911x_init(smsc911x_cfg);
+   *gpmc_cur = gpmc_smsc911x_init(smsc911x_cfg);
+   if (*gpmc_cur)
+   gpmc_data.num_device++, gpmc_cur++;
+   else
+   pr_err(error: gpmc smsc911x setup\n);
 }
 
 #else
-- 
1.7.10

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


[PATCH v4 00/39] OMAP GPMC driver conversion

2012-05-01 Thread Afzal Mohammed
Hi,

GPMC driver conversion patch series. Some peripherals has GPMC helper
functions, these has been modified to cater to the needs of GPMC
driver. All the boards using GPMC has been adapted to use the new
GPMC driver.

GPMC HWMOD entry for OMAP2/3 has been added. On OMAP3, kernel does
spit omap_hwmod: gpmc: cannot be enabled for reset (3), but
peripherals connected via GPMC are working. Really shaky about OMAP2
GPMC HWMOD entry. Would be helpful if someone can help me in resolving
warning on OMAP3  verify whether OMAP2 entry is proper. The series
adapts to HWMOD.

Drivers, NAND  OneNAND of OMAP has been modified to make use of GPMC
changes  cleaned up the now unnecessary exported symbol usages.

This series has been made on top of,
5e136da Linux-omap rebuilt: Updated to -rc5,
A patch by Javier Martinez Canillas jav...@dowhile0.org,
OMAP3: igep0020: Add support for Micron NAND Flash storage memory,
has also been incorporated into the series as this was necessary for
igep0020 board.

This has been tested on omap3 evm (SMSC911x)  beagle board (NAND)

I would need help to get these changes tested on other boards using
GPMC. Expected problematic boards are those having OMAP2xxx SoCs,
apollon board. In the case of apollon, in addition to it being
OMAP2xxx, it was modified to use gpmc_smc91x_init instead of directly
writing to configuration registers.

Additional features that currently boards in mainline does not make
use of like, waitpin interrupt handling, changes to leverage revision
6 IP differences has not been incorporated.

GPMC driver now provides NAND driver with GPMC-NAND registers so that
OMAP NAND driver can handle those by itself instead of using exported
symbols.

Acquiring CS for NAND has also been incorporated, it has been made as
a separate patch as it is felt that this should probably go away,
explained in the relevant patch.

GPMC (General Purpose Memory Controller) in brief:
GPMC is an unified memory controller dedicated to interfacing external
memory devices like
 Asynchronous SRAM like memories and application specific integrated circuit 
devices.
 Asynchronous, synchronous, and page mode burst NOR flash devices NAND flash
 Pseudo-SRAM devices

GPMC details can be referred in AM335X Technical Reference Manual
@ http://www.ti.com/lit/pdf/spruh73

v4: Handle wait pin (except for interrupts), enhance configuration
 timing interface of GPMC to take care of all boards. Dynamic
allocation of interrupt instead of static. Convert remaining
peripherals to work with GPMC driver. Handle acquiring NAND CS#,
adapt to HWMOD, update HWMOD OMAP2/3 entries, other minor
commenst on v3.
v3: Single device structure passed from platform for peripherals using
multiple CS instead of using multiple device structure having a few
redundant data, handle interrupts, GPMC NAND handling by GPMC NAND
driver instead of GPMC driver
v2: Avoid code movement that kept similar code together (for easy review)

TODO: Cleanup

Regards
Afzal

Afzal Mohammed (38):
  ARM: OMAP2+: gpmc: driver conversion
  ARM: OMAP2+: gpmc: Adapt to HWMOD
  ARM: OMAP2+: gpmc: register details for nand driver
  ARM: OMAP2+: gpmc: Acquire NAND CS value
  ARM: OMAP2+: nand: create platform data structure
  ARM: OMAP2+: onenand: return value in init function
  ARM: OMAP2+: gpmc-nand: Adapt to use gpmc driver
  ARM: OMAP2+: gpmc-onenand: Adapt to use gpmc driver
  ARM: OMAP2+: flash: Adapt to gpmc driver
  ARM: OMAP2+: gpmc-smsc911x: Adapt to use gpmc driver
  ARM: OMAP2+: gpmc-smc91x: Adapt to use gpmc driver
  ARM: OMAP2+: gpmc-tusb6010: Adapt to gpmc driver
  ARM: OMAP3: hwmod data: add gpmc
  ARM: OMAP2xxx: hwmod data: add gpmc
  mtd: nand: omap2: obtain memory from resource
  mtd: nand: omap2: use gpmc provided irqs
  mtd: nand: omap2: handle nand on gpmc
  mtd: onenand: omap: obtain memory from resource
  ARM: OMAP2+: board omap3evm: gpmc driver adaptation
  ARM: OMAP2+: board omap3beagle: gpmc driver adaptation
  ARM: OMAP2+: board apollon: gpmc driver adaptation
  ARM: OMAP2+: board h4: gpmc driver adaptation
  ARM: OMAP2+: board 3630sdp: gpmc driver adaptation
  ARM: OMAP2+: board 3430sdp: gpmc driver adaptation
  ARM: OMAP2+: board 2430sdp: gpmc driver adaptation
  ARM: OMAP2+: board cm-t3517: gpmc driver adaptation
  ARM: OMAP2+: board cm-t35: gpmc driver adaptation
  ARM: OMAP2+: board ldp: gpmc driver adaptation
  ARM: OMAP2+: board n8x0: gpmc driver adaptation
  ARM: OMAP2+: board omap3logic: gpmc driver adaptation
  ARM: OMAP2+: board omap3pandora: gpmc driver adaptation
  ARM: OMAP2+: board omap3stalker: gpmc driver adaptation
  ARM: OMAP2+: board omap4pcm049: gpmc driver adaptation
  ARM: OMAP2+: board overo: gpmc driver adaptation
  ARM: OMAP2+: board rm680: gpmc driver adaptation
  ARM: OMAP2+: board rx51: gpmc driver adaptation
  ARM: OMAP2+: board zoom-debugboard: gpmc driver adaptation
  ARM: OMAP2+: board igep0020: gpmc driver adaptation

Javier Martinez Canillas (1):
  OMAP3: igep0020: Add support

[PATCH v4 02/39] ARM: OMAP2+: gpmc: Adapt to HWMOD

2012-05-01 Thread Afzal Mohammed
Create API for platforms to adapt gpmc to HWMOD

Signed-off-by: Afzal Mohammed af...@ti.com
---
 arch/arm/mach-omap2/gpmc.c |   52 +++-
 arch/arm/plat-omap/include/plat/gpmc.h |1 +
 2 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 12916f3..c8d07bb 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -33,6 +33,8 @@
 
 #include plat/sdrc.h
 
+#include plat/omap_device.h
+
 /* GPMC register offsets */
 #define GPMC_REVISION  0x00
 #define GPMC_SYSCONFIG 0x10
@@ -276,6 +278,31 @@ unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
return ticks * gpmc_get_fclk_period() / 1000;
 }
 
+int __init omap_init_gpmc(struct gpmc_pdata *pdata)
+{
+   struct omap_hwmod *oh;
+   struct platform_device *pdev;
+   char *name = omap-gpmc;
+   char *oh_name = gpmc;
+
+   pdata-clk_prd = gpmc_get_fclk_period();
+
+   oh = omap_hwmod_lookup(oh_name);
+   if (!oh) {
+   pr_err(Could not look up %s\n, oh_name);
+   return -ENODEV;
+   }
+
+   pdev = omap_device_build(name, -1, oh, pdata,
+   sizeof(*pdata), NULL, 0, 0);
+   if (IS_ERR(pdev)) {
+   WARN(1, Can't build omap_device for %s:%s.\n,
+   name, oh-name);
+   return PTR_ERR(pdev);
+   }
+
+   return 0;
+}
 #ifdef DEBUG
 static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
   int time, const char *name)
@@ -843,24 +870,19 @@ static __devinit void gpmc_mem_init(void)
 
 static int __init gpmc_init(void)
 {
-   int ret = -EINVAL;
-   char *ck = NULL;
-
-   if (cpu_is_omap24xx()) {
-   ck = core_l3_ck;
-   } else if (cpu_is_omap34xx()) {
-   ck = gpmc_fck;
-   } else if (cpu_is_omap44xx()) {
-   ck = gpmc_ck;
-   }
+   char *oh_name = gpmc;
+   struct omap_hwmod *oh;
 
-   if (WARN_ON(!ck))
-   return ret;
+   oh = omap_hwmod_lookup(oh_name);
+   if (!oh) {
+   pr_err(Could not look up %s\n, oh_name);
+   return -ENODEV;
+   }
 
-   gpmc_l3_clk = clk_get(NULL, ck);
+   gpmc_l3_clk = clk_get(NULL, oh-main_clk);
if (IS_ERR(gpmc_l3_clk)) {
-   printk(KERN_ERR Could not get GPMC clock %s\n, ck);
-   BUG();
+   pr_err(error: clk_get on %s\n, oh-main_clk);
+   return -EINVAL;
}
 
clk_enable(gpmc_l3_clk);
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h 
b/arch/arm/plat-omap/include/plat/gpmc.h
index 2eedd99..c5cf020 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -217,6 +217,7 @@ struct gpmc_pdata {
 };
 
 extern int gpmc_cs_reconfigure(char *name, int id, struct gpmc_cs_data *cs);
+extern int omap_init_gpmc(struct gpmc_pdata *pdata);
 
 extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
 extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps);
-- 
1.7.10

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


<    1   2   3   4   5   6   7   >