Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
541d5d02
Commit
541d5d02
authored
Nov 30, 2005
by
Ladislav Michl
Committed by
Tony Lindgren
Nov 30, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] ARM: OMAP: NAND flash driver model
NAND flash driver model
parent
5ff4cea4
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
369 additions
and
311 deletions
+369
-311
arch/arm/mach-omap1/board-h2.c
arch/arm/mach-omap1/board-h2.c
+93
-13
arch/arm/mach-omap1/board-h3.c
arch/arm/mach-omap1/board-h3.c
+93
-12
arch/arm/mach-omap1/board-perseus2.c
arch/arm/mach-omap1/board-perseus2.c
+45
-10
drivers/mtd/nand/omap-nand-flash.c
drivers/mtd/nand/omap-nand-flash.c
+124
-264
include/asm-arm/arch-omap/board-h2.h
include/asm-arm/arch-omap/board-h2.h
+0
-4
include/asm-arm/arch-omap/board-h3.h
include/asm-arm/arch-omap/board-h3.h
+0
-4
include/asm-arm/arch-omap/board-perseus2.h
include/asm-arm/arch-omap/board-perseus2.h
+0
-4
include/asm-arm/mach/flash.h
include/asm-arm/mach/flash.h
+14
-0
No files found.
arch/arm/mach-omap1/board-h2.c
View file @
541d5d02
...
...
@@ -24,6 +24,7 @@
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <asm/hardware.h>
...
...
@@ -40,7 +41,7 @@
extern
int
omap_gpio_init
(
void
);
static
struct
mtd_partition
h2_partitions
[]
=
{
static
struct
mtd_partition
h2_
nor_
partitions
[]
=
{
/* bootloader (U-Boot, etc) in first sector */
{
.
name
=
"bootloader"
,
...
...
@@ -71,26 +72,83 @@ static struct mtd_partition h2_partitions[] = {
}
};
static
struct
flash_platform_data
h2_
flash
_data
=
{
static
struct
flash_platform_data
h2_
nor
_data
=
{
.
map_name
=
"cfi_probe"
,
.
width
=
2
,
.
parts
=
h2_partitions
,
.
nr_parts
=
ARRAY_SIZE
(
h2_partitions
),
.
parts
=
h2_
nor_
partitions
,
.
nr_parts
=
ARRAY_SIZE
(
h2_
nor_
partitions
),
};
static
struct
resource
h2_
flash
_resource
=
{
static
struct
resource
h2_
nor
_resource
=
{
/* This is on CS3, wherever it's mapped */
.
flags
=
IORESOURCE_MEM
,
};
static
struct
platform_device
h2_
flash
_device
=
{
static
struct
platform_device
h2_
nor
_device
=
{
.
name
=
"omapflash"
,
.
id
=
0
,
.
dev
=
{
.
platform_data
=
&
h2_
flash
_data
,
.
platform_data
=
&
h2_
nor
_data
,
},
.
num_resources
=
1
,
.
resource
=
&
h2_flash_resource
,
.
resource
=
&
h2_nor_resource
,
};
static
struct
mtd_partition
h2_nand_partitions
[]
=
{
#if 0
/* REVISIT: enable these partitions if you make NAND BOOT
* work on your H2 (rev C or newer); published versions of
* x-load only support P2 and H3.
*/
{
.name = "xloader",
.offset = 0,
.size = 64 * 1024,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
{
.name = "bootloader",
.offset = MTDPART_OFS_APPEND,
.size = 256 * 1024,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
{
.name = "params",
.offset = MTDPART_OFS_APPEND,
.size = 192 * 1024,
},
{
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = 2 * SZ_1M,
},
#endif
{
.
name
=
"filesystem"
,
.
size
=
MTDPART_SIZ_FULL
,
.
offset
=
MTDPART_OFS_APPEND
,
},
};
/* dip switches control NAND chip access: 8 bit, 16 bit, or neither */
static
struct
nand_platform_data
h2_nand_data
=
{
.
options
=
NAND_SAMSUNG_LP_OPTIONS
,
.
parts
=
h2_nand_partitions
,
.
nr_parts
=
ARRAY_SIZE
(
h2_nand_partitions
),
};
static
struct
resource
h2_nand_resource
=
{
.
flags
=
IORESOURCE_MEM
,
};
static
struct
platform_device
h2_nand_device
=
{
.
name
=
"omapnand"
,
.
id
=
0
,
.
dev
=
{
.
platform_data
=
&
h2_nand_data
,
},
.
num_resources
=
1
,
.
resource
=
&
h2_nand_resource
,
};
static
struct
resource
h2_smc91x_resources
[]
=
{
...
...
@@ -114,7 +172,8 @@ static struct platform_device h2_smc91x_device = {
};
static
struct
platform_device
*
h2_devices
[]
__initdata
=
{
&
h2_flash_device
,
&
h2_nor_device
,
&
h2_nand_device
,
&
h2_smc91x_device
,
};
...
...
@@ -174,13 +233,34 @@ static struct omap_board_config_kernel h2_config[] = {
{
OMAP_TAG_LCD
,
&
h2_lcd_config
},
};
#define H2_NAND_RB_GPIO_PIN 62
static
int
h2_nand_dev_ready
(
struct
nand_platform_data
*
data
)
{
return
omap_get_gpio_datain
(
H2_NAND_RB_GPIO_PIN
);
}
static
void
__init
h2_init
(
void
)
{
/* NOTE: revC boards support NAND-boot, which can put NOR on CS2B
* and NAND (either 16bit or 8bit) on CS3.
/* Here we assume the NOR boot config: NOR on CS3 (possibly swapped
* to address 0 by a dip switch), NAND on CS2B. The NAND driver will
* notice whether a NAND chip is enabled at probe time.
*
* FIXME revC boards (and H3) support NAND-boot, with a dip switch to
* put NOR on CS2B and NAND (which on H2 may be 16bit) on CS3. Try
* detecting that in code here, to avoid probing every possible flash
* configuration...
*/
h2_flash_resource
.
end
=
h2_flash_resource
.
start
=
omap_cs3_phys
();
h2_flash_resource
.
end
+=
SZ_32M
-
1
;
h2_nor_resource
.
end
=
h2_nor_resource
.
start
=
omap_cs3_phys
();
h2_nor_resource
.
end
+=
SZ_32M
-
1
;
h2_nand_resource
.
end
=
h2_nand_resource
.
start
=
OMAP_CS2B_PHYS
;
h2_nand_resource
.
end
+=
SZ_4K
-
1
;
if
(
!
(
omap_request_gpio
(
H2_NAND_RB_GPIO_PIN
)))
h2_nand_data
.
dev_ready
=
h2_nand_dev_ready
;
omap_cfg_reg
(
L3_1610_FLASH_CS2B_OE
);
omap_cfg_reg
(
M8_1610_FLASH_CS2B_WE
);
/* MMC: card detect and WP */
// omap_cfg_reg(U19_ARMIO1); /* CD */
...
...
arch/arm/mach-omap1/board-h3.c
View file @
541d5d02
...
...
@@ -22,6 +22,7 @@
#include <linux/platform_device.h>
#include <linux/errno.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <asm/setup.h>
...
...
@@ -41,7 +42,7 @@
extern
int
omap_gpio_init
(
void
);
static
struct
mtd_partition
h3
_partitions
[]
=
{
static
struct
mtd_partition
nor
_partitions
[]
=
{
/* bootloader (U-Boot, etc) in first sector */
{
.
name
=
"bootloader"
,
...
...
@@ -72,26 +73,80 @@ static struct mtd_partition h3_partitions[] = {
}
};
static
struct
flash_platform_data
h3_flash
_data
=
{
static
struct
flash_platform_data
nor
_data
=
{
.
map_name
=
"cfi_probe"
,
.
width
=
2
,
.
parts
=
h3
_partitions
,
.
nr_parts
=
ARRAY_SIZE
(
h3
_partitions
),
.
parts
=
nor
_partitions
,
.
nr_parts
=
ARRAY_SIZE
(
nor
_partitions
),
};
static
struct
resource
h3_flash
_resource
=
{
static
struct
resource
nor
_resource
=
{
/* This is on CS3, wherever it's mapped */
.
flags
=
IORESOURCE_MEM
,
};
static
struct
platform_device
flash
_device
=
{
static
struct
platform_device
nor
_device
=
{
.
name
=
"omapflash"
,
.
id
=
0
,
.
dev
=
{
.
platform_data
=
&
h3_flash
_data
,
.
platform_data
=
&
nor
_data
,
},
.
num_resources
=
1
,
.
resource
=
&
h3_flash_resource
,
.
resource
=
&
nor_resource
,
};
static
struct
mtd_partition
nand_partitions
[]
=
{
#if 0
/* REVISIT: enable these partitions if you make NAND BOOT work */
{
.name = "xloader",
.offset = 0,
.size = 64 * 1024,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
{
.name = "bootloader",
.offset = MTDPART_OFS_APPEND,
.size = 256 * 1024,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
{
.name = "params",
.offset = MTDPART_OFS_APPEND,
.size = 192 * 1024,
},
{
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = 2 * SZ_1M,
},
#endif
{
.
name
=
"filesystem"
,
.
size
=
MTDPART_SIZ_FULL
,
.
offset
=
MTDPART_OFS_APPEND
,
},
};
/* dip switches control NAND chip access: 8 bit, 16 bit, or neither */
static
struct
nand_platform_data
nand_data
=
{
.
options
=
NAND_SAMSUNG_LP_OPTIONS
,
.
parts
=
nand_partitions
,
.
nr_parts
=
ARRAY_SIZE
(
nand_partitions
),
};
static
struct
resource
nand_resource
=
{
.
flags
=
IORESOURCE_MEM
,
};
static
struct
platform_device
nand_device
=
{
.
name
=
"omapnand"
,
.
id
=
0
,
.
dev
=
{
.
platform_data
=
&
nand_data
,
},
.
num_resources
=
1
,
.
resource
=
&
nand_resource
,
};
static
struct
resource
smc91x_resources
[]
=
{
...
...
@@ -139,7 +194,8 @@ static struct platform_device intlat_device = {
};
static
struct
platform_device
*
devices
[]
__initdata
=
{
&
flash_device
,
&
nor_device
,
&
nand_device
,
&
smc91x_device
,
&
intlat_device
,
};
...
...
@@ -182,11 +238,36 @@ static struct omap_board_config_kernel h3_config[] = {
{
OMAP_TAG_LCD
,
&
h3_lcd_config
},
};
#define H3_NAND_RB_GPIO_PIN 10
static
int
nand_dev_ready
(
struct
nand_platform_data
*
data
)
{
return
omap_get_gpio_datain
(
H3_NAND_RB_GPIO_PIN
);
}
static
void
__init
h3_init
(
void
)
{
h3_flash_resource
.
end
=
h3_flash_resource
.
start
=
omap_cs3_phys
();
h3_flash_resource
.
end
+=
OMAP_CS3_SIZE
-
1
;
(
void
)
platform_add_devices
(
devices
,
ARRAY_SIZE
(
devices
));
/* Here we assume the NOR boot config: NOR on CS3 (possibly swapped
* to address 0 by a dip switch), NAND on CS2B. The NAND driver will
* notice whether a NAND chip is enabled at probe time.
*
* H3 support NAND-boot, with a dip switch to put NOR on CS2B and NAND
* (which on H2 may be 16bit) on CS3. Try detecting that in code here,
* to avoid probing every possible flash configuration...
*/
nor_resource
.
end
=
nor_resource
.
start
=
omap_cs3_phys
();
nor_resource
.
end
+=
SZ_32M
-
1
;
nand_resource
.
end
=
nand_resource
.
start
=
OMAP_CS2B_PHYS
;
nand_resource
.
end
+=
SZ_4K
-
1
;
if
(
!
(
omap_request_gpio
(
H3_NAND_RB_GPIO_PIN
)))
nand_data
.
dev_ready
=
nand_dev_ready
;
/* GPIO10 Func_MUX_CTRL reg bit 29:27, Configure V2 to mode1 as GPIO */
/* GPIO10 pullup/down register, Enable pullup on GPIO10 */
omap_cfg_reg
(
V2_1710_GPIO10
);
platform_add_devices
(
devices
,
ARRAY_SIZE
(
devices
));
omap_board_config
=
h3_config
;
omap_board_config_size
=
ARRAY_SIZE
(
h3_config
);
omap_serial_init
();
...
...
arch/arm/mach-omap1/board-perseus2.c
View file @
541d5d02
...
...
@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <asm/hardware.h>
...
...
@@ -44,7 +45,7 @@ static struct resource smc91x_resources[] = {
},
};
static
struct
mtd_partition
p2
_partitions
[]
=
{
static
struct
mtd_partition
nor
_partitions
[]
=
{
/* bootloader (U-Boot, etc) in first sector */
{
.
name
=
"bootloader"
,
...
...
@@ -75,27 +76,47 @@ static struct mtd_partition p2_partitions[] = {
},
};
static
struct
flash_platform_data
p2_flash
_data
=
{
static
struct
flash_platform_data
nor
_data
=
{
.
map_name
=
"cfi_probe"
,
.
width
=
2
,
.
parts
=
p2
_partitions
,
.
nr_parts
=
ARRAY_SIZE
(
p2
_partitions
),
.
parts
=
nor
_partitions
,
.
nr_parts
=
ARRAY_SIZE
(
nor
_partitions
),
};
static
struct
resource
p2_flash
_resource
=
{
static
struct
resource
nor
_resource
=
{
.
start
=
OMAP_CS0_PHYS
,
.
end
=
OMAP_CS0_PHYS
+
SZ_32M
-
1
,
.
flags
=
IORESOURCE_MEM
,
};
static
struct
platform_device
p2_flash
_device
=
{
static
struct
platform_device
nor
_device
=
{
.
name
=
"omapflash"
,
.
id
=
0
,
.
dev
=
{
.
platform_data
=
&
p2_flash
_data
,
.
platform_data
=
&
nor
_data
,
},
.
num_resources
=
1
,
.
resource
=
&
p2_flash_resource
,
.
resource
=
&
nor_resource
,
};
static
struct
nand_platform_data
nand_data
=
{
.
options
=
NAND_SAMSUNG_LP_OPTIONS
,
};
static
struct
resource
nand_resource
=
{
.
start
=
OMAP_CS3_PHYS
,
.
end
=
OMAP_CS3_PHYS
+
SZ_4K
-
1
,
.
flags
=
IORESOURCE_MEM
,
};
static
struct
platform_device
nand_device
=
{
.
name
=
"omapnand"
,
.
id
=
0
,
.
dev
=
{
.
platform_data
=
&
nand_data
,
},
.
num_resources
=
1
,
.
resource
=
&
nand_resource
,
};
static
struct
platform_device
smc91x_device
=
{
...
...
@@ -106,10 +127,18 @@ static struct platform_device smc91x_device = {
};
static
struct
platform_device
*
devices
[]
__initdata
=
{
&
p2_flash_device
,
&
nor_device
,
&
nand_device
,
&
smc91x_device
,
};
#define P2_NAND_RB_GPIO_PIN 62
static
int
nand_dev_ready
(
struct
nand_platform_data
*
data
)
{
return
omap_get_gpio_datain
(
P2_NAND_RB_GPIO_PIN
);
}
static
struct
omap_uart_config
perseus2_uart_config
__initdata
=
{
.
enabled_uarts
=
((
1
<<
0
)
|
(
1
<<
1
)),
};
...
...
@@ -126,7 +155,13 @@ static struct omap_board_config_kernel perseus2_config[] = {
static
void
__init
omap_perseus2_init
(
void
)
{
(
void
)
platform_add_devices
(
devices
,
ARRAY_SIZE
(
devices
));
if
(
!
(
omap_request_gpio
(
P2_NAND_RB_GPIO_PIN
)))
nand_data
.
dev_ready
=
nand_dev_ready
;
omap_cfg_reg
(
L3_1610_FLASH_CS2B_OE
);
omap_cfg_reg
(
M8_1610_FLASH_CS2B_WE
);
platform_add_devices
(
devices
,
ARRAY_SIZE
(
devices
));
omap_board_config
=
perseus2_config
;
omap_board_config_size
=
ARRAY_SIZE
(
perseus2_config
);
...
...
drivers/mtd/nand/omap-nand-flash.c
View file @
541d5d02
/*
* drivers/mtd/nand/omap-nand-flash.c
*
* Copyright (c) 2004 Texas Instruments
* Jian Zhang <jzhang@ti.com>
* Copyright (c) 2004 Texas Instruments, Jian Zhang <jzhang@ti.com>
* Copyright (c) 2004 David Brownell
*
* Derived from drivers/mtd/autcpu12.c
*
* Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de>
*
* 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.
*
* Overview:
* This is a device driver for the NAND flash device found on the
* TI H3/H2 boards. It supports 16-bit 32MiB Samsung k9f5616 chip.
*
*/
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <asm/io.h>
#include <asm/arch/hardware.h>
#include <asm/arch/gpio.h>
#include <asm/arch/mux.h>
#include <asm/arch/tc.h>
#include <asm/sizes.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/flash.h>
#include <asm/arch/tc.h>
#define H3_NAND_RB_GPIO_PIN 10
#define H2_NAND_RB_GPIO_PIN 62
#define P2_NAND_RB_GPIO_PIN 62
#define NETSTAR_NAND_RB_GPIO_PIN 1
/*
* MTD structure for H3 board
*/
static
struct
mtd_info
*
omap_nand_mtd
=
NULL
;
static
void
__iomem
*
omap_nand_flash_base
;
#include <asm/io.h>
#include <asm/arch/hardware.h>
/*
* Define partitions for flash devices
*/
#define DRIVER_NAME "omapnand"
#ifdef CONFIG_MTD_PARTITIONS
static
struct
mtd_partition
static_partition
[]
=
{
{
.
name
=
"Booting Image"
,
.
offset
=
0
,
.
size
=
64
*
1024
,
.
mask_flags
=
MTD_WRITEABLE
/* force read-only */
},
{
.
name
=
"U-Boot"
,
.
offset
=
MTDPART_OFS_APPEND
,
.
size
=
256
*
1024
,
.
mask_flags
=
MTD_WRITEABLE
/* force read-only */
},
{
.
name
=
"U-Boot Environment"
,
.
offset
=
MTDPART_OFS_APPEND
,
.
size
=
192
*
1024
},
{
.
name
=
"Kernel"
,
.
offset
=
MTDPART_OFS_APPEND
,
.
size
=
2
*
SZ_1M
},
{
.
name
=
"File System"
,
.
size
=
MTDPART_SIZ_FULL
,
.
offset
=
MTDPART_OFS_APPEND
,
},
};
const
char
*
part_probes
[]
=
{
"cmdlinepart"
,
NULL
,
};
static
const
char
*
part_probes
[]
=
{
"cmdlinepart"
,
NULL
};
#endif
/* H2/H3 maps two address LSBs to CLE and ALE; MSBs make CS_2B */
#define MASK_CLE 0x02
#define MASK_ALE 0x04
struct
omap_nand_info
{
struct
nand_platform_data
*
pdata
;
struct
mtd_partition
*
parts
;
struct
mtd_info
mtd
;
struct
nand_chip
nand
;
};
/*
* hardware specific access to control-lines
*/
* NOTE: boards may use different bits for these!!
*/
#define MASK_CLE 0x02
#define MASK_ALE 0x04
static
void
omap_nand_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
{
struct
nand_chip
*
this
=
mtd
->
priv
;
u
32
IO_ADDR_W
=
(
u32
)
this
->
IO_ADDR_W
;
u
nsigned
long
IO_ADDR_W
=
(
unsigned
long
)
this
->
IO_ADDR_W
;
IO_ADDR_W
&=
~
(
MASK_ALE
|
MASK_CLE
);
switch
(
cmd
){
switch
(
cmd
)
{
case
NAND_CTL_SETCLE
:
IO_ADDR_W
|=
MASK_CLE
;
break
;
case
NAND_CTL_CLRCLE
:
IO_ADDR_W
&=
~
MASK_CLE
;
break
;
case
NAND_CTL_SETALE
:
IO_ADDR_W
|=
MASK_ALE
;
break
;
case
NAND_CTL_CLRALE
:
IO_ADDR_W
&=
~
MASK_ALE
;
break
;
}
this
->
IO_ADDR_W
=
(
void
__iomem
*
)
IO_ADDR_W
;
}
/*
* chip busy R/B detection
*/
static
int
omap_nand_ready
(
struct
mtd_info
*
mtd
)
{
if
(
machine_is_omap_h3
())
return
omap_get_gpio_datain
(
H3_NAND_RB_GPIO_PIN
);
if
(
machine_is_omap_h2
())
return
omap_get_gpio_datain
(
H2_NAND_RB_GPIO_PIN
);
if
(
machine_is_omap_perseus2
())
return
omap_get_gpio_datain
(
H2_NAND_RB_GPIO_PIN
);
if
(
machine_is_netstar
())
return
omap_get_gpio_datain
(
NETSTAR_NAND_RB_GPIO_PIN
);
return
0
;
}
/* Scan to find existance of the device at omap_nand_flash_base.
This also allocates oob and data internal buffers */
static
int
__init
probe_nand_chip
(
void
)
static
int
omap_nand_dev_ready
(
struct
mtd_info
*
mtd
)
{
struct
nand_chip
*
this
;
this
=
(
struct
nand_chip
*
)
(
&
omap_nand_mtd
[
1
]);
/* Initialize structures */
memset
((
char
*
)
this
,
0
,
sizeof
(
struct
nand_chip
));
this
->
IO_ADDR_R
=
omap_nand_flash_base
;
this
->
IO_ADDR_W
=
omap_nand_flash_base
;
this
->
options
=
NAND_SAMSUNG_LP_OPTIONS
;
this
->
hwcontrol
=
omap_nand_hwcontrol
;
this
->
eccmode
=
NAND_ECC_SOFT
;
/* try 16-bit chip first */
this
->
options
|=
NAND_BUSWIDTH_16
;
if
(
nand_scan
(
omap_nand_mtd
,
1
))
{
if
(
machine_is_omap_h3
())
return
-
ENXIO
;
/* then try 8-bit chip for H2 */
memset
((
char
*
)
this
,
0
,
sizeof
(
struct
nand_chip
));
this
->
IO_ADDR_R
=
omap_nand_flash_base
;
this
->
IO_ADDR_W
=
omap_nand_flash_base
;
this
->
options
=
NAND_SAMSUNG_LP_OPTIONS
;
this
->
hwcontrol
=
omap_nand_hwcontrol
;
this
->
eccmode
=
NAND_ECC_SOFT
;
if
(
nand_scan
(
omap_nand_mtd
,
1
))
{
return
-
ENXIO
;
}
}
struct
omap_nand_info
*
info
=
container_of
(
mtd
,
struct
omap_nand_info
,
mtd
);
return
0
;
return
info
->
pdata
->
dev_ready
(
info
->
pdata
)
;
}
static
char
nand1_name
[]
=
"nand"
;
/*
* Main initialization routine
*/
int
__init
omap_nand_init
(
void
)
static
int
__devinit
omap_nand_probe
(
struct
device
*
dev
)
{
struct
nand_chip
*
this
;
struct
mtd_partition
*
dynamic_partition
=
0
;
int
err
=
0
;
int
nandboot
=
0
;
if
(
!
(
machine_is_omap_h2
()
||
machine_is_omap_h3
()
||
machine_is_netstar
()
||
machine_is_omap_perseus2
()))
return
-
ENODEV
;
struct
omap_nand_info
*
info
;
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
struct
nand_platform_data
*
pdata
=
pdev
->
dev
.
platform_data
;
struct
resource
*
res
=
pdev
->
resource
;
unsigned
long
size
=
res
->
end
-
res
->
start
+
1
;
int
err
;
info
=
kmalloc
(
sizeof
(
struct
omap_nand_info
),
GFP_KERNEL
);
if
(
!
info
)
return
-
ENOMEM
;
memset
(
info
,
0
,
sizeof
(
struct
omap_nand_info
));
if
(
!
request_mem_region
(
res
->
start
,
size
,
dev
->
driver
->
name
))
{
err
=
-
EBUSY
;
goto
out_free_info
;
}
/* Allocate memory for MTD device structure and private data */
omap_nand_mtd
=
kmalloc
(
sizeof
(
struct
mtd_info
)
+
sizeof
(
struct
nand_chip
),
GFP_KERNEL
);
if
(
!
omap_nand_mtd
)
{
printk
(
KERN_WARNING
"Unable to allocate NAND MTD device structure.
\n
"
);
info
->
nand
.
IO_ADDR_R
=
ioremap
(
res
->
start
,
size
);
if
(
!
info
->
nand
.
IO_ADDR_R
)
{
err
=
-
ENOMEM
;
goto
out
;
goto
out
_release_mem_region
;
}
info
->
nand
.
IO_ADDR_W
=
info
->
nand
.
IO_ADDR_R
;
info
->
nand
.
hwcontrol
=
omap_nand_hwcontrol
;
info
->
nand
.
eccmode
=
NAND_ECC_SOFT
;
info
->
nand
.
options
=
pdata
->
options
;
if
(
pdata
->
dev_ready
)
info
->
nand
.
dev_ready
=
omap_nand_dev_ready
;
else
info
->
nand
.
chip_delay
=
20
;
/* Get pointer to private data */
this
=
(
struct
nand_chip
*
)
(
&
omap_nand_mtd
[
1
]);
/* Initialize structures */
memset
((
char
*
)
omap_nand_mtd
,
0
,
sizeof
(
struct
mtd_info
)
+
sizeof
(
struct
nand_chip
));
/* Link the private data with the MTD structure */
omap_nand_mtd
->
priv
=
this
;
if
(
machine_is_omap_h2
()
||
machine_is_omap_perseus2
())
{
/* FIXME on H2, R/B needs M7_1610_GPIO62 ... */
this
->
chip_delay
=
15
;
omap_cfg_reg
(
L3_1610_FLASH_CS2B_OE
);
omap_cfg_reg
(
M8_1610_FLASH_CS2B_WE
);
}
else
if
(
machine_is_omap_h3
())
{
if
(
omap_request_gpio
(
H3_NAND_RB_GPIO_PIN
)
!=
0
)
{
printk
(
KERN_ERR
"NAND: Unable to get GPIO pin for R/B, use delay
\n
"
);
/* 15 us command delay time */
this
->
chip_delay
=
15
;
}
else
{
/* GPIO10 for input. it is in GPIO1 module */
omap_set_gpio_direction
(
H3_NAND_RB_GPIO_PIN
,
1
);
info
->
mtd
.
name
=
pdev
->
dev
.
bus_id
;
info
->
mtd
.
priv
=
&
info
->
nand
;
/* GPIO10 Func_MUX_CTRL reg bit 29:27, Configure V2 to mode1 as GPIO */
/* GPIO10 pullup/down register, Enable pullup on GPIO10 */
omap_cfg_reg
(
V2_1710_GPIO10
);
info
->
pdata
=
pdata
;
this
->
dev_ready
=
omap_nand_ready
;
}
}
else
if
(
machine_is_netstar
())
{
if
(
omap_request_gpio
(
NETSTAR_NAND_RB_GPIO_PIN
)
!=
0
)
{
printk
(
KERN_ERR
"NAND: Unable to get GPIO pin for R/B, use delay
\n
"
);
/* 15 us command delay time */
this
->
chip_delay
=
15
;
}
else
{
omap_set_gpio_direction
(
NETSTAR_NAND_RB_GPIO_PIN
,
1
);
this
->
dev_ready
=
omap_nand_ready
;
}
}
/* try the first address */
omap_nand_flash_base
=
ioremap
(
OMAP_NAND_FLASH_START1
,
SZ_4K
);
omap_nand_mtd
->
name
=
nand1_name
;
if
(
probe_nand_chip
()){
nandboot
=
1
;
/* try the second address */
iounmap
(
omap_nand_flash_base
);
omap_nand_flash_base
=
ioremap
(
OMAP_NAND_FLASH_START2
,
SZ_4K
);
if
(
probe_nand_chip
()){
iounmap
(
omap_nand_flash_base
);
/* DIP switches on H2 and some other boards change between 8 and 16 bit
* bus widths for flash. Try the other width if the first try fails.
*/
if
(
nand_scan
(
&
info
->
mtd
,
1
))
{
info
->
nand
.
options
^=
NAND_BUSWIDTH_16
;
if
(
nand_scan
(
&
info
->
mtd
,
1
))
{
err
=
-
ENXIO
;
goto
out_mtd
;
goto
out_iounmap
;
}
}
info
->
mtd
.
owner
=
THIS_MODULE
;
/* Register the partitions */
switch
(
omap_nand_mtd
->
size
)
{
case
SZ_128M
:
if
(
!
(
machine_is_netstar
()))
goto
out_unsupported
;
/* fall through */
case
SZ_64M
:
if
(
!
(
machine_is_netstar
()
||
machine_is_omap_perseus2
()))
goto
out_unsupported
;
/* fall through */
case
SZ_32M
:
#ifdef CONFIG_MTD_PARTITIONS
err
=
parse_mtd_partitions
(
omap_nand_mtd
,
part_probes
,
&
dynamic_partition
,
0
);
err
=
parse_mtd_partitions
(
&
info
->
mtd
,
part_probes
,
&
info
->
parts
,
0
);
if
(
err
>
0
)
err
=
add_mtd_partitions
(
omap_nand_mtd
,
dynamic_partition
,
err
);
else
if
(
nandboot
)
err
=
add_mtd_partitions
(
omap_nand_mtd
,
static_partition
,
ARRAY_SIZE
(
static_partition
));
add_mtd_partitions
(
&
info
->
mtd
,
info
->
parts
,
err
);
else
if
(
err
<
0
&&
pdata
->
parts
)
add_mtd_partitions
(
&
info
->
mtd
,
pdata
->
parts
,
pdata
->
nr_parts
);
else
#endif
err
=
add_mtd_device
(
omap_nand_mtd
);
if
(
err
)
goto
out_buf
;
break
;
out_unsupported:
default:
printk
(
KERN_WARNING
"Unsupported NAND device
\n
"
);
err
=
-
ENXIO
;
goto
out_buf
;
}
add_mtd_device
(
&
info
->
mtd
);
goto
out
;
dev_set_drvdata
(
&
pdev
->
dev
,
info
)
;
out_buf:
nand_release
(
omap_nand_mtd
);
if
(
this
->
dev_ready
)
{
if
(
machine_is_omap_h2
())
omap_free_gpio
(
H2_NAND_RB_GPIO_PIN
);
else
if
(
machine_is_omap_perseus2
())
omap_free_gpio
(
P2_NAND_RB_GPIO_PIN
);
else
if
(
machine_is_omap_h3
())
omap_free_gpio
(
H3_NAND_RB_GPIO_PIN
);
else
if
(
machine_is_netstar
())
omap_free_gpio
(
NETSTAR_NAND_RB_GPIO_PIN
);
}
iounmap
(
omap_nand_flash_base
);
return
0
;
out_iounmap:
iounmap
(
info
->
nand
.
IO_ADDR_R
);
out_release_mem_region:
release_mem_region
(
res
->
start
,
size
);
out_free_info:
kfree
(
info
);
out_mtd:
kfree
(
omap_nand_mtd
);
out:
return
err
;
}
module_init
(
omap_nand_init
);
/*
* Clean up routine
*/
static
void
__exit
omap_nand_cleanup
(
void
)
static
int
__devexit
omap_nand_remove
(
struct
device
*
dev
)
{
struct
nand_chip
*
this
=
omap_nand_mtd
->
priv
;
if
(
this
->
dev_ready
)
{
if
(
machine_is_omap_h2
())
omap_free_gpio
(
H2_NAND_RB_GPIO_PIN
);
else
if
(
machine_is_omap_h2
())
omap_free_gpio
(
H2_NAND_RB_GPIO_PIN
);
else
if
(
machine_is_omap_h3
())
omap_free_gpio
(
H3_NAND_RB_GPIO_PIN
);
else
if
(
machine_is_netstar
())
omap_free_gpio
(
NETSTAR_NAND_RB_GPIO_PIN
);
}
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
struct
omap_nand_info
*
info
=
dev_get_drvdata
(
&
pdev
->
dev
);
dev_set_drvdata
(
&
pdev
->
dev
,
NULL
);
/* Release NAND device, its internal structures and partitions */
nand_release
(
&
info
->
mtd
);
iounmap
(
info
->
nand
.
IO_ADDR_R
);
kfree
(
info
);
return
0
;
}
/* nand_release frees MTD partitions, MTD structure
and nand internal buffers*/
nand_release
(
omap_nand_mtd
);
kfree
(
omap_nand_mtd
);
static
struct
device_driver
omap_nand_driver
=
{
.
name
=
DRIVER_NAME
,
.
bus
=
&
platform_bus_type
,
.
probe
=
omap_nand_probe
,
.
remove
=
__devexit_p
(
omap_nand_remove
),
};
MODULE_ALIAS
(
DRIVER_NAME
);
iounmap
(
omap_nand_flash_base
);
static
int
__init
omap_nand_init
(
void
)
{
return
driver_register
(
&
omap_nand_driver
);
}
module_exit
(
omap_nand_cleanup
);
static
void
__exit
omap_nand_exit
(
void
)
{
driver_unregister
(
&
omap_nand_driver
);
}
module_init
(
omap_nand_init
);
module_exit
(
omap_nand_exit
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Jian Zhang <jzhang@ti.com>"
);
MODULE_DESCRIPTION
(
"Glue layer for NAND flash on H2/H3 boards"
);
MODULE_AUTHOR
(
"Jian Zhang <jzhang@ti.com> (and others)"
);
MODULE_DESCRIPTION
(
"Glue layer for NAND flash on TI OMAP boards"
);
include/asm-arm/arch-omap/board-h2.h
View file @
541d5d02
...
...
@@ -34,9 +34,5 @@
/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
#define OMAP1610_ETHR_START 0x04000300
/* Samsung NAND flash at CS2B or CS3(NAND Boot) */
#define OMAP_NAND_FLASH_START1 0x0A000000
/* CS2B */
#define OMAP_NAND_FLASH_START2 0x0C000000
/* CS3 */
#endif
/* __ASM_ARCH_OMAP_H2_H */
include/asm-arm/arch-omap/board-h3.h
View file @
541d5d02
...
...
@@ -30,10 +30,6 @@
/* In OMAP1710 H3 the Ethernet is directly connected to CS1 */
#define OMAP1710_ETHR_START 0x04000300
/* Samsung NAND flash at CS2B or CS3(NAND Boot) */
#define OMAP_NAND_FLASH_START1 0x0A000000
/* CS2B */
#define OMAP_NAND_FLASH_START2 0x0C000000
/* CS3 */
#define MAXIRQNUM (IH_BOARD_BASE)
#define MAXFIQNUM MAXIRQNUM
#define MAXSWINUM MAXIRQNUM
...
...
include/asm-arm/arch-omap/board-perseus2.h
View file @
541d5d02
...
...
@@ -42,8 +42,4 @@
#define NR_IRQS (MAXIRQNUM + 1)
/* Samsung NAND flash at CS2B or CS3(NAND Boot) */
#define OMAP_NAND_FLASH_START1 0x0A000000
/* CS2B */
#define OMAP_NAND_FLASH_START2 0x0C000000
/* CS3 */
#endif
include/asm-arm/mach/flash.h
View file @
541d5d02
...
...
@@ -36,4 +36,18 @@ struct flash_platform_data {
unsigned
int
nr_parts
;
};
/**
* struct nand_platform_data - platform data describing NAND flash banks
* @dev_ready: tests if the NAND flash is ready (READY signal is high)
* @options: bitmask for nand_chip.options
* @parts: optional array of mtd_partitions for static partitioning
* @nr_parts: number of mtd_partitions for static partitoning
*/
struct
nand_platform_data
{
int
(
*
dev_ready
)(
struct
nand_platform_data
*
data
);
unsigned
int
options
;
struct
mtd_partition
*
parts
;
unsigned
int
nr_parts
;
};
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment