From patchwork Thu Nov 19 14:16:38 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: vimal singh X-Patchwork-Id: 38839 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [18.85.46.34]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 2BDAA1007D1 for ; Fri, 20 Nov 2009 01:25:50 +1100 (EST) Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.69 #1 (Red Hat Linux)) id 1NB7vL-00010L-Uk; Thu, 19 Nov 2009 14:23:51 +0000 Received: from mail-bw0-f212.google.com ([209.85.218.212]) by bombadil.infradead.org with esmtp (Exim 4.69 #1 (Red Hat Linux)) id 1NB7vB-0000v5-3N for linux-mtd@lists.infradead.org; Thu, 19 Nov 2009 14:23:48 +0000 Received: by bwz4 with SMTP id 4so2755581bwz.2 for ; Thu, 19 Nov 2009 06:23:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:from:date:message-id :subject:to:cc:content-type; bh=Dv1BdZtmVaSe/pgN++WTgGd6sO5rnBaH/upS85RnmRo=; b=tsuOlPDfPY4VJ0t1Ft+mRK/sn/rYNwDXEO8aSLloA3D+PYNJgrFWrurcpmBJuBsHIn BSBswhqwnZtT4w/xJU0IjD+vEQHHmtqv/gAMtSqVV7scRuTY2qKPrpHk299X6RhyTqkC U8HV6MXqXmqJp4FfdhiGxyacWLeaciRlXSOws= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:from:date:message-id:subject:to:cc:content-type; b=H3drilVcGyGjNuYjoEX4ABvQC5g5IF+5AROqMJ6RL8GragNSlCYvLE0xaZq8f3fbPn fb/Kp3jkDsURm0pAV6Wr4ZBIB1Sn58INn82BqELvMnx9E3qOENSkwmmC3+xxcb9nq97U UKLx1g2IGO0cAGJUEdtc+Qb3duWBzkxAdFf0o= MIME-Version: 1.0 Received: by 10.204.154.135 with SMTP id o7mr1542225bkw.201.1258640619833; Thu, 19 Nov 2009 06:23:39 -0800 (PST) From: Vimal Singh Date: Thu, 19 Nov 2009 19:46:38 +0530 Message-ID: Subject: [PATCH-v6 1/4] OMAP2/3: Add support for flash on SDP boards To: linux-omap@vger.kernel.org, Linux MTD X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20091119_092341_503247_CAED513A X-CRM114-Status: GOOD ( 32.72 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.2.5 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- _SUMMARY_ Cc: Tony Lindgren , vimal singh X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From ac109bb5f47577b323673699a94f9b6a4a7e2431 Mon Sep 17 00:00:00 2001 From: Vimal Singh Date: Thu, 19 Nov 2009 19:01:11 +0530 Subject: [PATCH] OMAP2/3: Add support for flash on SDP boards Add support for flash on SDP boards. NAND, NOR and OneNAND are supported. This patch also implements Tony's comments on: http://marc.info/?l=linux-omap&m=125787938923028&w=2 This is done by creating 'mach-omap2/gpmc-nand.c' file, to handle GPMC related setups for the device driver. Only tested on 3430SDP (ES2 and ES3.1), somebody please test on 2430SDP and check the chips select for 2430SDP. Also note that: For OneNAND: in the earlier 2430SDP code the kernel partition was set to only 1MB instead of 2MB on 3430SDP. If people want the old partition sizes back on 2430SDP, please provide a patch. For NAND: 'U-Boot', 'Boot Env' and 'Kernel' partitions sizes increased by few blocks to provide few spare blocks for NAND bab block management in u-boot. If people want old partition sizes, please provide a patch. Signed-off-by: Vimal Singh Cc: Tony Lindgren --- arch/arm/mach-omap2/Makefile | 5 + arch/arm/mach-omap2/board-2430sdp.c | 2 + arch/arm/mach-omap2/board-3430sdp.c | 2 + arch/arm/mach-omap2/board-sdp-flash.c | 315 +++++++++++++++++++++++++++ arch/arm/mach-omap2/gpmc-nand.c | 128 +++++++++++ arch/arm/plat-omap/include/plat/board-sdp.h | 15 ++ arch/arm/plat-omap/include/plat/gpmc.h | 4 +- arch/arm/plat-omap/include/plat/nand.h | 6 + drivers/mtd/nand/omap2.c | 33 +-- 9 files changed, 488 insertions(+), 22 deletions(-) create mode 100644 arch/arm/mach-omap2/board-sdp-flash.c create mode 100644 arch/arm/mach-omap2/gpmc-nand.c create mode 100644 arch/arm/plat-omap/include/plat/board-sdp.h if (pdata == NULL) { @@ -910,24 +905,25 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) info->mtd.name = dev_name(&pdev->dev); info->mtd.owner = THIS_MODULE; + info->nand.options |= pdata->devsize ? NAND_BUSWIDTH_16 : 0; + info->nand.options |= NAND_SKIP_BBTSCAN; + err = gpmc_cs_request(info->gpmc_cs, NAND_IO_SIZE, &info->phys_base); if (err < 0) { dev_err(&pdev->dev, "Cannot request GPMC CS\n"); goto out_free_info; } - /* Enable RD PIN Monitoring Reg */ - if (pdata->dev_ready) { - val = gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG1); - val |= WR_RD_PIN_MONITORING; - gpmc_cs_write_reg(info->gpmc_cs, GPMC_CS_CONFIG1, val); + if (pdata->nand_setup != NULL) { + err = pdata->nand_setup((void __iomem *)info->phys_base); + if (err < 0) { + dev_err(&pdev->dev, "NAND platform setup failed: " + "%d\n", err); + goto out_free_cs; + } + info->setup = pdata->nand_setup; } - val = gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG7); - val &= ~(0xf << 8); - val |= (0xc & 0xf) << 8; - gpmc_cs_write_reg(info->gpmc_cs, GPMC_CS_CONFIG7, val); - /* NAND write protect off */ omap_nand_wp(&info->mtd, NAND_WP_OFF); @@ -963,11 +959,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) info->nand.chip_delay = 50; } - info->nand.options |= NAND_SKIP_BBTSCAN; - if ((gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG1) & 0x3000) - == 0x1000) - info->nand.options |= NAND_BUSWIDTH_16; - if (use_prefetch) { /* copy the virtual address of nand base for fifo access */ info->nand_pref_fifo_add = info->nand.IO_ADDR_R; diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 59b0ccc..b0e5b46 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -56,6 +56,7 @@ obj-$(CONFIG_OMAP_IOMMU) += $(iommu-y) obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o \ + board-sdp-flash.o \ mmc-twl4030.o obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o \ @@ -69,6 +70,7 @@ obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o \ obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o \ mmc-twl4030.o obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \ + board-sdp-flash.o \ mmc-twl4030.o obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \ @@ -105,3 +107,6 @@ obj-y += $(onenand-m) $(onenand-y) smc91x-$(CONFIG_SMC91X) := gpmc-smc91x.o obj-y += $(smc91x-m) $(smc91x-y) + +nand-$(CONFIG_MTD_NAND_OMAP2) := gpmc-nand.o +obj-y += $(nand-m) $(nand-y) diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index db9374b..5676ab9 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -38,6 +38,7 @@ #include #include +#include #include "mmc-twl4030.h" #define SDP2430_CS0_BASE 0x04000000 @@ -205,6 +206,7 @@ static void __init omap_2430sdp_init(void) twl4030_mmc_init(mmc); usb_musb_init(); board_smc91x_init(); + sdp_flash_init(); /* Turn off secondary LCD backlight */ ret = gpio_request(SECONDARY_LCD_GPIO, "Secondary LCD backlight"); diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 491364e..f2ed1ab 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -41,6 +41,7 @@ #include #include +#include #include "sdram-qimonda-hyb18m512160af-6.h" #include "mmc-twl4030.h" @@ -521,6 +522,7 @@ static void __init omap_3430sdp_init(void) omap_serial_init(); usb_musb_init(); board_smc91x_init(); + sdp_flash_init(); enable_board_wakeup_source(); usb_ehci_init(&ehci_pdata); } diff --git a/arch/arm/mach-omap2/board-sdp-flash.c b/arch/arm/mach-omap2/board-sdp-flash.c new file mode 100644 index 0000000..e5fc309 --- /dev/null +++ b/arch/arm/mach-omap2/board-sdp-flash.c @@ -0,0 +1,315 @@ +/* + * board-sdp-flash.c + * + * Copyright (C) 2009 Nokia Corporation + * Copyright (C) 2009 Texas Instruments + * + * Modified from mach-omap2/board-3430sdp-flash.c + * Author: Vimal Singh + * + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include + +#define REG_FPGA_REV 0x10 +#define REG_FPGA_DIP_SWITCH_INPUT2 0x60 +#define MAX_SUPPORTED_GPMC_CONFIG 3 + +#define DEBUG_BASE 0x08000000 /* debug board */ + +#define PDC_NOR 1 +#define PDC_NAND 2 +#define PDC_ONENAND 3 +#define DBG_MPDB 4 + +/* various memory sizes */ +#define FLASH_SIZE_SDPV1 SZ_64M /* NOR flash (64 Meg aligned) */ +#define FLASH_SIZE_SDPV2 SZ_128M /* NOR flash (256 Meg aligned) */ + +/* + * SDP3430 V2 Board CS organization + * Different from SDP3430 V1. Now 4 switches used to specify CS + * + * See also the Switch S8 settings in the comments. + * + * REVISIT: Add support for 2430 SDP + */ +static const unsigned char chip_sel_sdp[][GPMC_CS_NUM] = { + {PDC_NOR, PDC_NAND, PDC_ONENAND, DBG_MPDB, 0, 0, 0, 0}, /* S8:1111 */ + {PDC_ONENAND, PDC_NAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1110 */ + {PDC_NAND, PDC_ONENAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1101 */ +}; + +static struct mtd_partition sdp_nor_partitions[] = { + /* bootloader (U-Boot, etc) in first sector */ + { + .name = "Bootloader-NOR", + .offset = 0, + .size = SZ_256K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + /* bootloader params in the next sector */ + { + .name = "Params-NOR", + .offset = MTDPART_OFS_APPEND, + .size = SZ_256K, + .mask_flags = 0, + }, + /* kernel */ + { + .name = "Kernel-NOR", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M, + .mask_flags = 0 + }, + /* file system */ + { + .name = "Filesystem-NOR", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0 + } +}; + +static struct flash_platform_data sdp_nor_data = { + .map_name = "cfi_probe", + .width = 2, + .parts = sdp_nor_partitions, + .nr_parts = ARRAY_SIZE(sdp_nor_partitions), +}; + +static struct resource sdp_nor_resource = { + .flags = IORESOURCE_MEM, +}; + +static struct platform_device sdp_nor_device = { + .name = "omapflash", + .id = 0, + .dev = { + .platform_data = &sdp_nor_data, + }, + .num_resources = 1, + .resource = &sdp_nor_resource, +}; + +#if defined(CONFIG_MTD_ONENAND_OMAP2) || \ + defined(CONFIG_MTD_ONENAND_OMAP2_MODULE) + +static struct mtd_partition board_onenand_partitions[] = { + { + .name = "X-Loader-OneNAND", + .offset = 0, + .size = 4 * (64 * 2048), + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .name = "U-Boot-OneNAND", + .offset = MTDPART_OFS_APPEND, + .size = 2 * (64 * 2048), + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .name = "U-Boot Environment-OneNAND", + .offset = MTDPART_OFS_APPEND, + .size = 1 * (64 * 2048), + }, + { + .name = "Kernel-OneNAND", + .offset = MTDPART_OFS_APPEND, + .size = 16 * (64 * 2048), + }, + { + .name = "File System-OneNAND", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct omap_onenand_platform_data board_onenand_data = { + .parts = board_onenand_partitions, + .nr_parts = ARRAY_SIZE(board_onenand_partitions), + .dma_channel = -1, /* disable DMA in OMAP OneNAND driver */ +}; + + +static void __init board_onenand_init(u8 cs) +{ + board_onenand_data.cs = cs; + gpmc_onenand_init(&board_onenand_data); +} + +#else + +static inline void board_onenand_init(u8 cs) +{ +} +#endif /* CONFIG_MTD_ONENAND_OMAP2 || CONFIG_MTD_ONENAND_OMAP2_MODULE */ + +static struct mtd_partition sdp_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 = 0x80000 */ + .size = 10 * (64 * 2048), + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "Boot Env-NAND", + + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c0000 */ + .size = 6 * (64 * 2048), + }, + { + .name = "Kernel-NAND", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */ + .size = 40 * (64 * 2048), + }, + { + .name = "File System - NAND", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, /* Offset = 0x780000 */ + }, +}; + +static struct omap_nand_platform_data sdp_nand_data = { + .parts = sdp_nand_partitions, + .nr_parts = ARRAY_SIZE(sdp_nand_partitions), + .nand_setup = NULL, + .dma_channel = -1, /* disable DMA in OMAP NAND driver */ + .dev_ready = NULL, + .devsize = 0, /* '0' for 8-bit, '1' for 16-bit device */ +}; + +static void __init board_nand_init(u8 cs) +{ + sdp_nand_data.cs = cs; + sdp_nand_data.gpmc_cs_baseaddr = (void *)(OMAP34XX_GPMC_VIRT + + GPMC_CS0_BASE + cs * GPMC_CS_SIZE); + sdp_nand_data.gpmc_baseaddr = (void *) (OMAP34XX_GPMC_VIRT); + + gpmc_nand_init(&sdp_nand_data); +} + +/** + * get_gpmc0_type - Reads the FPGA DIP_SWITCH_INPUT_REGISTER2 to get + * the various cs values. + */ +static u8 get_gpmc0_type(void) +{ + u8 cs = 0; + void __iomem *fpga_map_addr; + + fpga_map_addr = ioremap(DEBUG_BASE, 4096); + if (!fpga_map_addr) + return -ENOMEM; + + if (!(__raw_readw(fpga_map_addr + REG_FPGA_REV))) + /* we dont have an DEBUG FPGA??? */ + /* Depend on #defines!! default to strata boot return param */ + goto unmap; + + /* S8-DIP-OFF = 1, S8-DIP-ON = 0 */ + cs = __raw_readw(fpga_map_addr + REG_FPGA_DIP_SWITCH_INPUT2) & 0xf; + + /* ES2.0 SDP's onwards 4 dip switches are provided for CS */ + if (omap_rev() >= OMAP3430_REV_ES1_0) + /* change (S8-1:4=DS-2:0) to (S8-4:1=DS-2:0) */ + cs = ((cs & 8) >> 3) | ((cs & 4) >> 1) | + ((cs & 2) << 1) | ((cs & 1) << 3); + else + /* change (S8-1:3=DS-2:0) to (S8-3:1=DS-2:0) */ + cs = ((cs & 4) >> 2) | (cs & 2) | ((cs & 1) << 2); +unmap: + iounmap(fpga_map_addr); + return cs; +} + +/** + * sdp3430_flash_init - Identify devices connected to GPMC and register. + * + * @return - void. + */ +void __init sdp_flash_init(void) +{ + u8 cs = 0; + u8 nandcs = GPMC_CS_NUM + 1; + u8 onenandcs = GPMC_CS_NUM + 1; + u8 idx; + unsigned char *config_sel = NULL; + int err; + + /* REVISIT: Is this return correct idx for 2430 SDP? + * for which cs configuration matches for 2430 SDP? + */ + idx = get_gpmc0_type(); + if (idx >= MAX_SUPPORTED_GPMC_CONFIG) { + printk(KERN_ERR "%s: Invalid chip select: %d\n", __func__, cs); + return; + } + config_sel = (unsigned char *)(chip_sel_sdp[idx]); + + while (cs < GPMC_CS_NUM) { + switch (config_sel[cs]) { + case PDC_NOR: + /* 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 *)&sdp_nor_resource.start); + sdp_nor_resource.end = sdp_nor_resource.start + + FLASH_SIZE_SDPV2 - 1; + } else { + err = gpmc_cs_request(cs, FLASH_SIZE_SDPV1 - 1, + (unsigned long *)&sdp_nor_resource.start); + sdp_nor_resource.end = sdp_nor_resource.start + + FLASH_SIZE_SDPV1 - 1; + } + if (err < 0) { + printk(KERN_ERR "NOR: Can't request GPMC CS\n"); + break; + } + if (platform_device_register(&sdp_nor_device) < 0) + printk(KERN_ERR + "Unable to register NOR device\n"); + break; + case PDC_NAND: + if (nandcs > GPMC_CS_NUM) + nandcs = cs; + break; + case PDC_ONENAND: + if (onenandcs > GPMC_CS_NUM) + onenandcs = cs; + break; + }; + cs++; + } + + if (onenandcs > GPMC_CS_NUM) + printk(KERN_INFO "OneNAND: Unable to find configuration " + " in GPMC\n "); + else + board_onenand_init(onenandcs); + + if (nandcs > GPMC_CS_NUM) + printk(KERN_INFO "NAND: Unable to find configuration " + " in GPMC\n "); + else + board_nand_init(nandcs); +} diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c new file mode 100644 index 0000000..a6bee9c --- /dev/null +++ b/arch/arm/mach-omap2/gpmc-nand.c @@ -0,0 +1,128 @@ +/* + * gpmc-nand.c + * + * Copyright (C) 2009 Texas Instruments + * Contacts: Vimal Singh + * + * 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 +#include +#include + +#include + +#include +#include +#include + +#define WR_RD_PIN_MONITORING 0x00600000 + +static struct omap_nand_platform_data *gpmc_nand_data; + +static struct resource gpmc_nand_resource = { + .flags = IORESOURCE_MEM, +}; + +static struct platform_device gpmc_nand_device = { + .name = "omap2-nand", + .id = 0, + .num_resources = 1, + .resource = &gpmc_nand_resource, +}; + +static int omap2_nand_gpmc_config(int cs, void __iomem *nand_base) +{ + struct gpmc_timings t; + int err; + + const int cs_rd_off = 36; + const int cs_wr_off = 36; + const int adv_on = 6; + const int adv_rd_off = 24; + const int adv_wr_off = 36; + const int oe_off = 48; + const int we_off = 30; + const int rd_cycle = 72; + const int wr_cycle = 72; + const int access = 54; + const int wr_data_mux_bus = 8; + const int wr_access = 30; + + memset(&t, 0, sizeof(t)); + t.sync_clk = 0; + t.cs_on = 0; + t.adv_on = gpmc_round_ns_to_ticks(adv_on); + + /* Read */ + t.adv_rd_off = gpmc_round_ns_to_ticks(adv_rd_off); + t.oe_on = t.adv_on; + t.access = gpmc_round_ns_to_ticks(access); + t.oe_off = gpmc_round_ns_to_ticks(oe_off); + t.cs_rd_off = gpmc_round_ns_to_ticks(cs_rd_off); + t.rd_cycle = gpmc_round_ns_to_ticks(rd_cycle); + + /* Write */ + t.adv_wr_off = gpmc_round_ns_to_ticks(adv_wr_off); + t.we_on = t.oe_on; + if (cpu_is_omap34xx()) { + t.wr_data_mux_bus = gpmc_round_ns_to_ticks(wr_data_mux_bus); + t.wr_access = gpmc_round_ns_to_ticks(wr_access); + } + t.we_off = gpmc_round_ns_to_ticks(we_off); + t.cs_wr_off = gpmc_round_ns_to_ticks(cs_wr_off); + t.wr_cycle = gpmc_round_ns_to_ticks(wr_cycle); + + /* Configure GPMC */ + gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, + GPMC_CONFIG1_DEVICESIZE(gpmc_nand_data->devsize) | + GPMC_CONFIG1_DEVICETYPE_NAND); + + err = gpmc_cs_set_timings(cs, &t); + if (err) + return err; + + return 0; +} + +static int gpmc_nand_setup(void __iomem *nand_base) +{ + struct device *dev = &gpmc_nand_device.dev; + + /* Set timings in GPMC */ + if (omap2_nand_gpmc_config(gpmc_nand_data->cs, nand_base) < 0) { + dev_err(dev, "Unable to set gpmc timings\n"); + return -EINVAL; + } + + return 0; +} + +void __init gpmc_nand_init(struct omap_nand_platform_data *_nand_data) +{ + unsigned int val; + + gpmc_nand_data = _nand_data; + gpmc_nand_data->nand_setup = gpmc_nand_setup; + gpmc_nand_device.dev.platform_data = gpmc_nand_data; + + /* Enable RD PIN Monitoring Reg */ + if (gpmc_nand_data->dev_ready) { + val = gpmc_cs_read_reg(gpmc_nand_data->cs, + GPMC_CS_CONFIG1); + val |= WR_RD_PIN_MONITORING; + gpmc_cs_write_reg(gpmc_nand_data->cs, + GPMC_CS_CONFIG1, val); + } + + val = gpmc_cs_read_reg(gpmc_nand_data->cs, GPMC_CS_CONFIG7); + val &= ~(0xf << 8); + val |= (0xc & 0xf) << 8; + gpmc_cs_write_reg(gpmc_nand_data->cs, GPMC_CS_CONFIG7, val); + + if (platform_device_register(&gpmc_nand_device) < 0) + printk(KERN_ERR "Unable to register NAND device\n"); +} diff --git a/arch/arm/plat-omap/include/plat/board-sdp.h b/arch/arm/plat-omap/include/plat/board-sdp.h new file mode 100644 index 0000000..a37dc7c --- /dev/null +++ b/arch/arm/plat-omap/include/plat/board-sdp.h @@ -0,0 +1,15 @@ +/* + * board-sdp.h + * + * Information structures for SDP-specific board config data + * + * Copyright (C) 2009 Nokia Corporation + * Copyright (C) 2009 Texas Instruments + * + * 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. + */ + +extern void sdp_flash_init(void); + diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 696e0ca..4090749 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -27,6 +27,8 @@ #define GPMC_CONFIG 0x50 #define GPMC_STATUS 0x54 +#define GPMC_CS0_BASE 0x60 +#define GPMC_CS_SIZE 0x30 #define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31) #define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 30) @@ -45,7 +47,7 @@ #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) -#define GPMC_CONFIG1_DEVICETYPE_NAND GPMC_CONFIG1_DEVICETYPE(1) +#define GPMC_CONFIG1_DEVICETYPE_NAND GPMC_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) diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 631a7be..164630b 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -21,4 +21,10 @@ struct omap_nand_platform_data { int dma_channel; void __iomem *gpmc_cs_baseaddr; void __iomem *gpmc_baseaddr; + int devsize; }; + +extern void gpmc_nand_init(struct omap_nand_platform_data *d); + +/* size (4 KiB) for IO mapping */ +#define NAND_IO_SIZE SZ_4K diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 1bb799f..41ffb19 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -30,12 +30,8 @@ #define DRIVER_NAME "omap2-nand" -/* size (4 KiB) for IO mapping */ -#define NAND_IO_SIZE SZ_4K - #define NAND_WP_OFF 0 #define NAND_WP_BIT 0x00000010 -#define WR_RD_PIN_MONITORING 0x00600000 #define GPMC_BUF_FULL 0x00000001 #define GPMC_BUF_EMPTY 0x00000000 @@ -139,6 +135,7 @@ struct omap_nand_info { struct mtd_partition *parts; struct nand_chip nand; struct platform_device *pdev; + int (*setup)(void __iomem *base); int gpmc_cs; unsigned long phys_base; @@ -882,8 +879,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) struct omap_nand_info *info; struct omap_nand_platform_data *pdata; int err; - unsigned long val; - pdata = pdev->dev.platform_data;