Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
arm
mach-omap2
gpmc-nand.c
Go to the documentation of this file.
1
/*
2
* gpmc-nand.c
3
*
4
* Copyright (C) 2009 Texas Instruments
5
* Vimal Singh <
[email protected]
>
6
*
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License version 2 as
9
* published by the Free Software Foundation.
10
*/
11
12
#include <linux/kernel.h>
13
#include <
linux/platform_device.h
>
14
#include <
linux/io.h
>
15
#include <
linux/mtd/nand.h
>
16
#include <
linux/platform_data/mtd-nand-omap2.h
>
17
18
#include <
asm/mach/flash.h
>
19
20
#include <
plat/gpmc.h
>
21
22
#include "
soc.h
"
23
24
static
struct
resource
gpmc_nand_resource[] = {
25
{
26
.flags =
IORESOURCE_MEM
,
27
},
28
{
29
.flags =
IORESOURCE_IRQ
,
30
},
31
{
32
.flags =
IORESOURCE_IRQ
,
33
},
34
};
35
36
static
struct
platform_device
gpmc_nand_device = {
37
.name =
"omap2-nand"
,
38
.id = 0,
39
.num_resources =
ARRAY_SIZE
(gpmc_nand_resource),
40
.resource = gpmc_nand_resource,
41
};
42
43
static
int
omap2_nand_gpmc_retime(
struct
omap_nand_platform_data
*gpmc_nand_data)
44
{
45
struct
gpmc_timings
t
;
46
int
err
;
47
48
if
(!gpmc_nand_data->
gpmc_t
)
49
return
0;
50
51
memset
(&
t
, 0,
sizeof
(
t
));
52
t
.sync_clk = gpmc_nand_data->
gpmc_t
->sync_clk;
53
t
.cs_on =
gpmc_round_ns_to_ticks
(gpmc_nand_data->
gpmc_t
->cs_on);
54
t
.adv_on =
gpmc_round_ns_to_ticks
(gpmc_nand_data->
gpmc_t
->adv_on);
55
56
/* Read */
57
t
.adv_rd_off =
gpmc_round_ns_to_ticks
(
58
gpmc_nand_data->
gpmc_t
->adv_rd_off);
59
t
.oe_on =
t
.adv_on;
60
t
.access =
gpmc_round_ns_to_ticks
(gpmc_nand_data->
gpmc_t
->access);
61
t
.oe_off =
gpmc_round_ns_to_ticks
(gpmc_nand_data->
gpmc_t
->oe_off);
62
t
.cs_rd_off =
gpmc_round_ns_to_ticks
(gpmc_nand_data->
gpmc_t
->cs_rd_off);
63
t
.rd_cycle =
gpmc_round_ns_to_ticks
(gpmc_nand_data->
gpmc_t
->rd_cycle);
64
65
/* Write */
66
t
.adv_wr_off =
gpmc_round_ns_to_ticks
(
67
gpmc_nand_data->
gpmc_t
->adv_wr_off);
68
t
.we_on =
t
.oe_on;
69
if
(
cpu_is_omap34xx
()) {
70
t
.wr_data_mux_bus =
gpmc_round_ns_to_ticks
(
71
gpmc_nand_data->
gpmc_t
->wr_data_mux_bus);
72
t
.wr_access =
gpmc_round_ns_to_ticks
(
73
gpmc_nand_data->
gpmc_t
->wr_access);
74
}
75
t
.we_off =
gpmc_round_ns_to_ticks
(gpmc_nand_data->
gpmc_t
->we_off);
76
t
.cs_wr_off =
gpmc_round_ns_to_ticks
(gpmc_nand_data->
gpmc_t
->cs_wr_off);
77
t
.wr_cycle =
gpmc_round_ns_to_ticks
(gpmc_nand_data->
gpmc_t
->wr_cycle);
78
79
/* Configure GPMC */
80
if
(gpmc_nand_data->
devsize
==
NAND_BUSWIDTH_16
)
81
gpmc_cs_configure
(gpmc_nand_data->
cs
,
GPMC_CONFIG_DEV_SIZE
, 1);
82
else
83
gpmc_cs_configure
(gpmc_nand_data->
cs
,
GPMC_CONFIG_DEV_SIZE
, 0);
84
gpmc_cs_configure
(gpmc_nand_data->
cs
,
85
GPMC_CONFIG_DEV_TYPE
,
GPMC_DEVICETYPE_NAND
);
86
gpmc_cs_configure
(gpmc_nand_data->
cs
,
GPMC_CONFIG_WP
, 0);
87
err =
gpmc_cs_set_timings
(gpmc_nand_data->
cs
, &
t
);
88
if
(err)
89
return
err
;
90
91
return
0;
92
}
93
94
int
__init
gpmc_nand_init
(
struct
omap_nand_platform_data
*gpmc_nand_data)
95
{
96
int
err = 0;
97
struct
device
*
dev
= &gpmc_nand_device.
dev
;
98
99
gpmc_nand_device.
dev
.platform_data = gpmc_nand_data;
100
101
err =
gpmc_cs_request
(gpmc_nand_data->
cs
,
NAND_IO_SIZE
,
102
(
unsigned
long
*)&gpmc_nand_resource[0].
start
);
103
if
(err < 0) {
104
dev_err
(dev,
"Cannot request GPMC CS\n"
);
105
return
err
;
106
}
107
108
gpmc_nand_resource[0].
end
= gpmc_nand_resource[0].
start
+
109
NAND_IO_SIZE
- 1;
110
111
gpmc_nand_resource[1].
start
=
112
gpmc_get_client_irq
(
GPMC_IRQ_FIFOEVENTENABLE
);
113
gpmc_nand_resource[2].
start
=
114
gpmc_get_client_irq
(
GPMC_IRQ_COUNT_EVENT
);
115
/* Set timings in GPMC */
116
err = omap2_nand_gpmc_retime(gpmc_nand_data);
117
if
(err < 0) {
118
dev_err
(dev,
"Unable to set gpmc timings: %d\n"
, err);
119
return
err
;
120
}
121
122
/* Enable RD PIN Monitoring Reg */
123
if
(gpmc_nand_data->
dev_ready
) {
124
gpmc_cs_configure
(gpmc_nand_data->
cs
,
GPMC_CONFIG_RDY_BSY
, 1);
125
}
126
127
gpmc_update_nand_reg
(&gpmc_nand_data->
reg
, gpmc_nand_data->
cs
);
128
129
err =
platform_device_register
(&gpmc_nand_device);
130
if
(err < 0) {
131
dev_err
(dev,
"Unable to register NAND device\n"
);
132
goto
out_free_cs;
133
}
134
135
return
0;
136
137
out_free_cs:
138
gpmc_cs_free
(gpmc_nand_data->
cs
);
139
140
return
err
;
141
}
Generated on Thu Jan 10 2013 13:00:42 for Linux Kernel by
1.8.2