From: Kevin Hilman <khilman@mvista.com>
To: linux-omap-open-source@linux.omap.com
Subject: [RFC/PATCH] ARM: OMAP: OneNAND support for 2430SDP
Date: Tue, 20 Mar 2007 17:40:30 -0700 [thread overview]
Message-ID: <20070321004030.424076000@mvista.com> (raw)
Adds platform device for use of existing OMAP2 driver. Also, the
following changes are made to the existing driver:
- add option for not using DMA (by passing dma_channel = -1)
- removes obsoleted pt_regs arg from interrupt handler
RFC: Notice the change to onenand_base.c which comments out the last
OOB chunk. Without this, it would not work. Previous drivers
for this board such as the 2.6.10-based MV kernel have this
same change. Anyone know what is going on here?
Signed-off-by: Kevin Hilman <khilman@mvista.com>
---
arch/arm/mach-omap2/Makefile | 3
arch/arm/mach-omap2/board-2430sdp-flash.c | 108 ++++++++++++++++++++++++++++++
arch/arm/mach-omap2/board-2430sdp.c | 4 +
arch/arm/mach-omap2/gpmc.c | 1
drivers/mtd/onenand/omap2.c | 103 +++++++++++++++++-----------
drivers/mtd/onenand/onenand_base.c | 2
include/asm-arm/arch-omap/gpmc.h | 7 +
include/asm-arm/arch-omap/onenand.h | 1
8 files changed, 187 insertions(+), 42 deletions(-)
Index: dev/arch/arm/mach-omap2/Makefile
===================================================================
--- dev.orig/arch/arm/mach-omap2/Makefile
+++ dev/arch/arm/mach-omap2/Makefile
@@ -20,7 +20,8 @@ mmu_mach-objs := mmu.o
# Specific board support
obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
-obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o
+obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o \
+ board-2430sdp-flash.o
obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o
obj-$(CONFIG_MACH_NOKIA_N800) += board-n800.o board-n800-flash.o \
board-n800-mmc.o board-n800-bt.o \
Index: dev/arch/arm/mach-omap2/board-2430sdp-flash.c
===================================================================
--- /dev/null
+++ dev/arch/arm/mach-omap2/board-2430sdp-flash.c
@@ -0,0 +1,108 @@
+/*
+ * linux/arch/arm/mach-omap2/board-2430sdp-flash.c
+ *
+ * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com>
+ * Author: Kevin Hilman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <asm/mach/flash.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/onenand_regs.h>
+
+#include <asm/io.h>
+#include <asm/arch/onenand.h>
+#include <asm/arch/board.h>
+#include <asm/arch/gpmc.h>
+
+#define ONENAND_MAP 0x20000000
+
+static struct mtd_partition onenand_partitions[] = {
+ {
+ .name = "(OneNAND)X-Loader",
+ .offset = 0,
+ .size = 4*(64*2048), /* 0-3 blks reserved.
+ Mandated by ROM code */
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "(OneNAND)U-Boot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 2*(64*2048),
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "(OneNAND)U-Boot Environment",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 1*(64*2048),
+ },
+ {
+ .name = "(OneNAND)Kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 4*(64*2048),
+ },
+ {
+ .name = "(OneNAND)File System",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap_onenand_platform_data sdp_onenand_data = {
+ .parts = onenand_partitions,
+ .nr_parts = ARRAY_SIZE(onenand_partitions),
+ .dma_channel = -1, /* disable DMA in OMAP OneNAND driver */
+};
+
+static struct platform_device sdp_onenand_device = {
+ .name = "omap2-onenand",
+ .id = -1,
+ .dev = {
+ .platform_data = &sdp_onenand_data,
+ },
+};
+
+void __init sdp2430_flash_init(void)
+{
+ unsigned long gpmc_base_add, gpmc_cs_base_add;
+ unsigned char cs=0;
+
+ gpmc_base_add = OMAP243X_GPMC_VIRT;
+ while (cs < GPMC_CS_NUM) {
+ int ret = 0;
+
+ /* Each GPMC set for a single CS is at offset 0x30 */
+ gpmc_cs_base_add = (gpmc_base_add + GPMC_CONFIG1_0 + (cs*0x30));
+
+ /* xloader/Uboot would have programmed the oneNAND
+ * base address for us This is a ugly hack. The proper
+ * way of doing this is to pass the setup of u-boot up
+ * to kernel using kernel params - something on the
+ * lines of machineID. Check if oneNAND is
+ * configured */
+ ret = __raw_readl(gpmc_cs_base_add + GPMC_CS_CONFIG7);
+ if ((ret & 0x3F) == (ONENAND_MAP >> 24)) {
+ /* Found it!! */
+ break;
+ }
+ cs++;
+ }
+ if (cs >= GPMC_CS_NUM) {
+ printk("OneNAND: Unable to find oneNAND configuration in GPMC "
+ " - not registering.\n");
+ return;
+ }
+
+ sdp_onenand_data.cs = cs;
+
+ if (platform_device_register(&sdp_onenand_device) < 0) {
+ printk(KERN_ERR "Unable to register OneNAND device\n");
+ return;
+ }
+}
Index: dev/arch/arm/mach-omap2/board-2430sdp.c
===================================================================
--- dev.orig/arch/arm/mach-omap2/board-2430sdp.c
+++ dev/arch/arm/mach-omap2/board-2430sdp.c
@@ -192,12 +192,16 @@ static struct omap_board_config_kernel s
{OMAP_TAG_UART, &sdp2430_uart_config},
};
+extern void __init sdp2430_flash_init(void);
+
static void __init omap_2430sdp_init(void)
{
platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
omap_board_config = sdp2430_config;
omap_board_config_size = ARRAY_SIZE(sdp2430_config);
omap_serial_init();
+
+ sdp2430_flash_init();
}
static void __init omap_2430sdp_map_io(void)
Index: dev/arch/arm/mach-omap2/gpmc.c
===================================================================
--- dev.orig/arch/arm/mach-omap2/gpmc.c
+++ dev/arch/arm/mach-omap2/gpmc.c
@@ -51,7 +51,6 @@
#define GPMC_CS0 0x60
#define GPMC_CS_SIZE 0x30
-#define GPMC_CS_NUM 8
#define GPMC_MEM_START 0x00000000
#define GPMC_MEM_END 0x3FFFFFFF
#define BOOT_ROM_SPACE 0x100000 /* 1MB */
Index: dev/drivers/mtd/onenand/omap2.c
===================================================================
--- dev.orig/drivers/mtd/onenand/omap2.c
+++ dev/drivers/mtd/onenand/omap2.c
@@ -80,8 +80,7 @@ static void omap2_onenand_dma_cb(int lch
complete(&info->dma_done);
}
-static irqreturn_t omap2_onenand_interrupt(int irq, void *dev_id,
- struct pt_regs *regs)
+static irqreturn_t omap2_onenand_interrupt(int irq, void *dev_id)
{
struct omap2_onenand *info = dev_id;
@@ -111,11 +110,15 @@ static int omap2_onenand_wait(struct mtd
omap2_onenand_writew(syscfg, info->onenand.base + ONENAND_REG_SYS_CFG1);
INIT_COMPLETION(info->irq_done);
- result = omap_get_gpio_datain(info->gpio_irq);
- if (result == -1) {
- ctrl = omap2_onenand_readw(info->onenand.base + ONENAND_REG_CTRL_STATUS);
- printk(KERN_ERR "onenand_wait: gpio error, state = %d, ctrl = 0x%04x\n", state, ctrl);
- return -EIO;
+ if (info->gpio_irq) {
+ result = omap_get_gpio_datain(info->gpio_irq);
+ if (result == -1) {
+ ctrl = omap2_onenand_readw(info->onenand.base + ONENAND_REG_CTRL_STATUS);
+ printk(KERN_ERR "onenand_wait: gpio error, state = %d, ctrl = 0x%04x\n", state, ctrl);
+ return -EIO;
+ }
+ } else {
+ result = 0;
}
if (result == 0) {
int retry_cnt = 0;
@@ -317,6 +320,11 @@ static int __devinit omap2_onenand_probe
init_completion(&info->dma_done);
info->gpmc_cs = pdata->cs;
info->gpio_irq = pdata->gpio_irq;
+ info->dma_channel = pdata->dma_channel;
+ if (info->dma_channel < 0) {
+ /* if -1, don't use DMA */
+ info->gpio_irq = 0;
+ }
r = gpmc_cs_request(info->gpmc_cs, ONENAND_IO_SIZE, &info->phys_base);
if (r < 0) {
@@ -345,31 +353,41 @@ static int __devinit omap2_onenand_probe
}
}
- if ((r = omap_request_gpio(info->gpio_irq)) < 0) {
- dev_err(&pdev->dev, "Failed to request GPIO%d for OneNAND\n",
- info->gpio_irq);
- goto err_iounmap;
- }
- omap_set_gpio_direction(info->gpio_irq, 1);
-
- if ((r = request_irq(OMAP_GPIO_IRQ(info->gpio_irq),
- omap2_onenand_interrupt, SA_TRIGGER_RISING,
- pdev->dev.driver->name, info)) < 0)
- goto err_release_gpio;
-
- r = omap_request_dma(0, pdev->dev.driver->name,
- omap2_onenand_dma_cb, (void *) info,
- &info->dma_channel);
- if (r == 0) {
- omap_set_dma_write_mode(info->dma_channel, OMAP_DMA_WRITE_NON_POSTED);
- omap_set_dma_src_data_pack(info->dma_channel, 1);
- omap_set_dma_src_burst_mode(info->dma_channel, OMAP_DMA_DATA_BURST_8);
- omap_set_dma_dest_data_pack(info->dma_channel, 1);
- omap_set_dma_dest_burst_mode(info->dma_channel, OMAP_DMA_DATA_BURST_8);
- } else {
- dev_info(&pdev->dev,
- "failed to allocate DMA for OneNAND, using PIO instead\n");
- info->dma_channel = -1;
+ if (info->gpio_irq) {
+ if ((r = omap_request_gpio(info->gpio_irq)) < 0) {
+ dev_err(&pdev->dev,
+ "Failed to request GPIO%d for OneNAND\n",
+ info->gpio_irq);
+ goto err_iounmap;
+ }
+ omap_set_gpio_direction(info->gpio_irq, 1);
+
+ if ((r = request_irq(OMAP_GPIO_IRQ(info->gpio_irq),
+ omap2_onenand_interrupt,
+ SA_TRIGGER_RISING,
+ pdev->dev.driver->name, info)) < 0)
+ goto err_release_gpio;
+ }
+
+ if (info->dma_channel >= 0) {
+ r = omap_request_dma(0, pdev->dev.driver->name,
+ omap2_onenand_dma_cb, (void *) info,
+ &info->dma_channel);
+ if (r == 0) {
+ omap_set_dma_write_mode(info->dma_channel,
+ OMAP_DMA_WRITE_NON_POSTED);
+ omap_set_dma_src_data_pack(info->dma_channel, 1);
+ omap_set_dma_src_burst_mode(info->dma_channel,
+ OMAP_DMA_DATA_BURST_8);
+ omap_set_dma_dest_data_pack(info->dma_channel, 1);
+ omap_set_dma_dest_burst_mode(info->dma_channel,
+ OMAP_DMA_DATA_BURST_8);
+ } else {
+ dev_info(&pdev->dev,
+ "failed to allocate DMA for OneNAND, "
+ "using PIO instead\n");
+ info->dma_channel = -1;
+ }
}
dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual base %p\n",
@@ -379,9 +397,12 @@ static int __devinit omap2_onenand_probe
info->mtd.name = pdev->dev.bus_id;
info->mtd.priv = &info->onenand;
info->mtd.owner = THIS_MODULE;
- info->onenand.wait = omap2_onenand_wait;
- info->onenand.read_bufferram = omap2_onenand_read_bufferram;
- info->onenand.write_bufferram = omap2_onenand_write_bufferram;
+
+ if (info->dma_channel >= 0) {
+ info->onenand.wait = omap2_onenand_wait;
+ info->onenand.read_bufferram = omap2_onenand_read_bufferram;
+ info->onenand.write_bufferram = omap2_onenand_write_bufferram;
+ }
if ((r = onenand_scan(&info->mtd, 1)) < 0)
goto err_release_dma;
@@ -404,9 +425,11 @@ err_release_onenand:
err_release_dma:
if (info->dma_channel != -1)
omap_free_dma(info->dma_channel);
- free_irq(OMAP_GPIO_IRQ(info->gpio_irq), info);
+ if (info->gpio_irq)
+ free_irq(OMAP_GPIO_IRQ(info->gpio_irq), info);
err_release_gpio:
- omap_free_gpio(info->gpio_irq);
+ if (info->gpio_irq)
+ omap_free_gpio(info->gpio_irq);
err_iounmap:
iounmap(info->onenand.base);
err_release_mem_region:
@@ -439,8 +462,10 @@ static int __devexit omap2_onenand_remov
omap_free_dma(info->dma_channel);
omap2_onenand_shutdown(pdev);
platform_set_drvdata(pdev, NULL);
- free_irq(OMAP_GPIO_IRQ(info->gpio_irq), info);
- omap_free_gpio(info->gpio_irq);
+ if (info->gpio_irq) {
+ free_irq(OMAP_GPIO_IRQ(info->gpio_irq), info);
+ omap_free_gpio(info->gpio_irq);
+ }
iounmap(info->onenand.base);
release_mem_region(info->phys_base, ONENAND_IO_SIZE);
kfree(info);
Index: dev/drivers/mtd/onenand/onenand_base.c
===================================================================
--- dev.orig/drivers/mtd/onenand/onenand_base.c
+++ dev/drivers/mtd/onenand/onenand_base.c
@@ -39,7 +39,7 @@ static struct nand_ecclayout onenand_oob
},
.oobfree = {
{2, 3}, {14, 2}, {18, 3}, {30, 2},
- {34, 3}, {46, 2}, {50, 3}, {62, 2}
+ {34, 3}, {46, 2}, {50, 3}, /* {62, 2} */
}
};
Index: dev/include/asm-arm/arch-omap/gpmc.h
===================================================================
--- dev.orig/include/asm-arm/arch-omap/gpmc.h
+++ dev/include/asm-arm/arch-omap/gpmc.h
@@ -11,6 +11,9 @@
#ifndef __OMAP2_GPMC_H
#define __OMAP2_GPMC_H
+/* Maximum Number of Chip Selects */
+#define GPMC_CS_NUM 8
+
#define GPMC_CS_CONFIG1 0x00
#define GPMC_CS_CONFIG2 0x04
#define GPMC_CS_CONFIG3 0x08
@@ -22,6 +25,10 @@
#define GPMC_CS_NAND_ADDRESS 0x20
#define GPMC_CS_NAND_DATA 0x24
+#define GPMC_CONFIG 0x50
+#define GPMC_STATUS 0x54
+#define GPMC_CONFIG1_0 0x60
+
#define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31)
#define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 30)
#define GPMC_CONFIG1_READTYPE_ASYNC (0 << 29)
Index: dev/include/asm-arm/arch-omap/onenand.h
===================================================================
--- dev.orig/include/asm-arm/arch-omap/onenand.h
+++ dev/include/asm-arm/arch-omap/onenand.h
@@ -17,4 +17,5 @@ struct omap_onenand_platform_data {
struct mtd_partition *parts;
int nr_parts;
int (*onenand_setup)(void __iomem *);
+ int dma_channel;
};
--
next reply other threads:[~2007-03-21 0:40 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-03-21 0:40 Kevin Hilman [this message]
2007-03-21 19:15 ` [RFC/PATCH] ARM: OMAP: OneNAND support for 2430SDP Jalori, Mohit
2007-03-21 19:50 ` Kevin Hilman
2007-03-22 1:06 ` Kyungmin Park
2007-03-22 3:14 ` Kevin Hilman
2007-03-22 4:50 ` Kyungmin Park
2007-03-22 5:02 ` Kyungmin Park
2007-03-22 16:53 ` Kevin Hilman
2007-03-23 4:40 ` Kyungmin Park
2007-04-26 17:35 ` Tony Lindgren
2007-04-30 22:34 ` Kevin Hilman
2007-05-02 17:45 ` Tony Lindgren
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070321004030.424076000@mvista.com \
--to=khilman@mvista.com \
--cc=linux-omap-open-source@linux.omap.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.