Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(348)

Side by Side Diff: board/tegra2/common/nand/HY27UF084G2B/tegra2_nand.c

Issue 6623073: Chromium: arm: tegra: Add NAND support (Closed) Base URL: http://git.chromium.org/git/u-boot-next.git@chromeos-v2010.09
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * (C) Copyright 2006 Detlev Zundel, dzu@denx.de
3 * (C) Copyright 2006 DENX Software Engineering
4 * (C) Copyright 2011 NVIDIA Corporation <www.nvidia.com>
5 *
6 * See file CREDITS for list of people who contributed to this
7 * project.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 * MA 02111-1307 USA
23 */
24
25 #include <common.h>
26 #include <asm/io.h>
27 #include <nand.h>
28 #include <asm/arch/gpio.h>
29 #include "tegra2_nand.h"
30
31 static int byte_count;
32
33 static struct nand_ecclayout nand_soft_eccoob = {
34 .oobfree = {
35 {.offset = 40, .length = 24 }}
36 };
37
38 /**
39 * tegra2_nand_read_byte - [DEFAULT] read one byte from the chip
40 * @mtd: MTD device structure
41 *
42 * Default read function for 8bit buswith
43 */
44 static uint8_t tegra2_nand_read_byte(struct mtd_info *mtd)
45 {
46 struct nand_chip *chip = mtd->priv;
47 int dword_read;
48
49 dword_read = readl(chip->IO_ADDR_R + NAND_RESP_0);
50 dword_read = dword_read >> (8 * byte_count);
51 byte_count ++;
52 return (uint8_t) dword_read;
53 }
54
55 /**
56 * tegra2_nand_write_buf - [DEFAULT] write buffer to chip
57 * @mtd: MTD device structure
58 * @buf: data buffer
59 * @len: number of bytes to write
60 *
61 * Default write function for 8bit buswith
62 */
63 static void tegra2_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
64 {
65 int i, j, l, l2;
66 struct nand_chip *chip = mtd->priv;
67
68 for (i = 0; i < len/4; i++)
69 {
70 l = ((int *)buf)[i];
71 writel(l, chip->IO_ADDR_W+ NAND_RESP_0);
72 /* Go, PIO, Tx, TRANS_SIZE=3 for 4 bytes, A_valid, CE0 */
73 writel(Bit31+Bit28+Bit27+(3<<20)+Bit19+Bit8, chip->IO_ADDR_W + N AND_COMMAND_0);
74 if (!tegra2_nand_waitfor_GO_cleared(mtd))
75 printf("Command timeout during write_buf\n");
76 }
77 if ((len % 4) != 0)
78 {
79 l = 0;
80 for (j=0; j<(len %4); j++)
81 {
82 l2 = (int) buf[i*4+j];
83 l |= (l2<< (8*j));
84 }
85 writel(l, chip->IO_ADDR_W+ NAND_RESP_0);
86 /* Go, PIO, Tx, TRANS_SIZE, A_valid, CE0 */
87 writel(Bit31+Bit28+Bit27+(((len % 4)-1)<<20)+Bit19+Bit8, chip->I O_ADDR_W + NAND_COMMAND_0);
88 if (!tegra2_nand_waitfor_GO_cleared(mtd))
89 printf("Command timeout during write_buf\n");
90 }
91 }
92
93 /**
94 * tegra2_nand_read_buf - [DEFAULT] read chip data into buffer
95 * @mtd: MTD device structure
96 * @buf: buffer to store date
97 * @len: number of bytes to read
98 *
99 * Default read function for 8bit buswith
100 */
101 static void tegra2_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
102 {
103 int i, j, l;
104 struct nand_chip *chip = mtd->priv;
105 int *buf_dword;
106
107 buf_dword = (int *) buf;
108 for (i = 0; i < len/4; i++)
109 {
110 /* Go, PIO, Rx, TRANS_SIZE=3 for 4 bytes, A_valid, CE0 */
111 writel(Bit31+Bit28+Bit26+(3<<20)+Bit19+Bit8, chip->IO_ADDR_W + N AND_COMMAND_0);
112 if (!tegra2_nand_waitfor_GO_cleared(mtd))
113 printf("Command timeout during read_buf\n");
114 l = readl(chip->IO_ADDR_R+ NAND_RESP_0);
115 buf_dword[i] = l;
116 }
117 if ((len % 4) != 0)
118 {
119 /* Go, PIO, Rx, TRANS_SIZE, A_valid, CE0 */
120 writel(Bit31+Bit28+Bit26+(((len % 4)-1)<<20)+Bit19+Bit8, chip->I O_ADDR_W + NAND_COMMAND_0);
121 if (!tegra2_nand_waitfor_GO_cleared(mtd))
122 printf("Command timeout during read_buf\n");
123 l = readl(chip->IO_ADDR_R+ NAND_RESP_0);
124 for (j=0; j<(len %4); j++)
125 {
126 buf[i*4+j] = (char) (l>>(8*j));
127 }
128 }
129 }
130
131 /*
132 * = 1 - ready
133 * 0 - not ready
134 */
135 static int tegra2_nand_waitfor_GO_cleared(struct mtd_info *mtd)
136 {
137 struct nand_chip *this = mtd->priv;
138 int i;
139
140 for (i=0; i< 100000; i++)
Tom Warren 2011/03/08 20:43:08 This value should be a #define somewhere, i.e. #de
141 {
142 if (!(readl(this->IO_ADDR_R + NAND_CMD_REG1_0) & Bit31))
143 break;
144 else
145 udelay(1);
146 }
147 if (i== 100000)
148 return 0;
149 return 1;
150 }
151
152 /*
153 * = 1 - ready
154 * 0 - not ready
155 */
156 static int tegra2_nand_dev_ready(struct mtd_info *mtd)
157 {
158 register struct nand_chip *chip = mtd->priv;
159 int status;
160
161 writel(NAND_CMD_STATUS, chip->IO_ADDR_W + NAND_CMD_REG1_0);
162 /* Go, CLE, PIO, Rx, CE0, 0+1 transfer byte */
163 writel(Bit31+Bit30+Bit28+Bit26+(0<<20)+Bit8, chip->IO_ADDR_W + NAND_COMM AND_0);
164 if (!(tegra2_nand_waitfor_GO_cleared(mtd)))
165 printf("NAND_CMD_STATUS command timeout\n");
166 udelay(1);
167 status = readl(chip->IO_ADDR_R + NAND_RESP_0);
168 if (status & NAND_STATUS_READY)
169 return 1;
170 return 0;
171 }
172
173 /*
174 * hardware specific access to control-lines
175 */
176 static void tegra2_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ct rl)
177 {
178 }
179
180 /**
181 * tegra2_nand_command - [DEFAULT] Send command to NAND device
182 * @mtd: MTD device structure
183 * @command: the command to be sent
184 * @column: the column address for this command, -1 if none
185 * @page_addr: the page address for this command, -1 if none
186 */
187 static void tegra2_nand_command(struct mtd_info *mtd, unsigned int command,
188 int column, int page_addr)
189 {
190 register struct nand_chip *chip = mtd->priv;
191
192 /*
193 * Write out the command to the device.
194 */
195 if (mtd->writesize < 2048) {
196 /* To DO */
Tom Warren 2011/03/08 20:43:08 How about a printf here saying writesize is too sm
197 }
198 else
199 {
200 /* Emulate NAND_CMD_READOOB */
201 if (command == NAND_CMD_READOOB)
202 {
203 column += mtd->writesize;
204 command = NAND_CMD_READ0;
205 }
206
207 if (column != -1 || page_addr != -1)
208 {
209 /* Serially input address */
210 if (column != -1)
211 {
212 /* Adjust columns for 16 bit buswidth */
213 if (chip->options & NAND_BUSWIDTH_16)
214 column >>= 1;
215 }
216 }
217 }
218
219 /*
220 * program and erase have their own busy handlers
221 * status and sequential in needs no delay
222 */
223 switch (command) {
224 case NAND_CMD_READID:
225 writel(NAND_CMD_READID, chip->IO_ADDR_W + NAND_CMD_REG1_0);
226 writel(Bit31+Bit30+Bit29+Bit28+Bit26+(3<<20)+Bit8, chip->IO_ADDR _W + NAND_COMMAND_0);
227 byte_count = 0;
228 break;
229 case NAND_CMD_READ0:
230 writel(NAND_CMD_READ0, chip->IO_ADDR_W + NAND_CMD_REG1_0);
231 writel(NAND_CMD_READSTART, chip->IO_ADDR_W + NAND_CMD_REG2_0);
232 writel((page_addr <<16)+ (column & 0xFFFF), chip->IO_ADDR_W + NA ND_ADDR_REG1_0);
233 writel(page_addr >>16, chip->IO_ADDR_W + NAND_ADDR_REG2_0);
234 /* Go, CLE, ALE, PIO, SEC_CMD, CE0, 4+1 address cycles */
235 writel(Bit31+Bit30+Bit29+Bit28+Bit25+Bit8+4, chip->IO_ADDR_W + N AND_COMMAND_0);
236 byte_count = 0;
237 break;
238 case NAND_CMD_SEQIN:
239 writel(NAND_CMD_SEQIN, chip->IO_ADDR_W + NAND_CMD_REG1_0);
240 writel(NAND_CMD_PAGEPROG, chip->IO_ADDR_W + NAND_CMD_REG2_0);
241 writel((page_addr <<16)+ (column & 0xFFFF), chip->IO_ADDR_W + NA ND_ADDR_REG1_0);
242 writel(page_addr >>16, chip->IO_ADDR_W + NAND_ADDR_REG2_0);
243 /* Go, CLE, ALE, PIO, SEC_CMD, AFT_DAT, CE0, 4+1 address cycles */
244 writel(Bit31+Bit30+Bit29+Bit28+Bit25+Bit24+Bit8+4, chip->IO_ADDR _W + NAND_COMMAND_0);
Tom Warren 2011/03/08 20:43:08 Some of these lines look to be too long (>80 chars
245 break;
246 case NAND_CMD_PAGEPROG:
247 writel(NAND_CMD_PAGEPROG, chip->IO_ADDR_W + NAND_CMD_REG1_0);
248 /* Go, CLE, CE0 */
249 writel(Bit31+Bit30+Bit8, chip->IO_ADDR_W + NAND_COMMAND_0);
250 break;
251 case NAND_CMD_ERASE1:
252 writel(NAND_CMD_ERASE1, chip->IO_ADDR_W + NAND_CMD_REG1_0);
253 writel(NAND_CMD_ERASE2, chip->IO_ADDR_W + NAND_CMD_REG2_0);
254 writel(page_addr, chip->IO_ADDR_W + NAND_ADDR_REG1_0);
255 /* Go, CLE, ALE, SEC_CMD, CE0, 2+1 address cycles */
256 writel(Bit31+Bit30+Bit29+Bit25+Bit8+2, chip->IO_ADDR_W + NAND_CO MMAND_0);
257 break;
258 case NAND_CMD_RNDOUT:
259 writel(NAND_CMD_RNDOUT, chip->IO_ADDR_W + NAND_CMD_REG1_0);
260 writel(NAND_CMD_RNDOUTSTART, chip->IO_ADDR_W + NAND_CMD_REG2_0);
261 writel((column & 0xFFFF), chip->IO_ADDR_W + NAND_ADDR_REG1_0);
262 /* Go, CLE, ALE, PIO, SEC_CMD, CE0, 1+1 address cycles */
263 writel(Bit31+Bit30+Bit29+Bit28+Bit25+Bit8+1, chip->IO_ADDR_W + N AND_COMMAND_0);
264 break;
265 case NAND_CMD_ERASE2:
266 return;
267 case NAND_CMD_STATUS:
268 writel(NAND_CMD_STATUS, chip->IO_ADDR_W + NAND_CMD_REG1_0);
269 /* Go, CLE, PIO, Rx, CE0, 0+1 transfer byte */
270 writel(Bit31+Bit30+Bit28+Bit26+(0<<20)+Bit8, chip->IO_ADDR_W + N AND_COMMAND_0);
271 byte_count = 0;
272 break;
273
274 case NAND_CMD_RESET:
275 writel(NAND_CMD_RESET, chip->IO_ADDR_W + NAND_CMD_REG1_0);
276 /* Go, CLE, CE0 */
277 writel(Bit31+Bit30+Bit8, chip->IO_ADDR_W + NAND_COMMAND_0);
278 break;
279 default:
280 /*
281 * If we don't have access to the busy pin, we apply the given
282 * command delay
283 */
284 if (!chip->dev_ready)
285 {
286 udelay(chip->chip_delay);
287 return;
288 }
289 }
290 if (!tegra2_nand_waitfor_GO_cleared(mtd))
291 printf("Command 0x%02X timeout\n", command);
292
293 if (command == NAND_CMD_READ0)
294 udelay(25);
295 else
296 udelay(1);
297 }
298
299 /*
300 * Board-specific NAND initialization. The following members of the
301 * argument are board-specific (per include/linux/mtd/nand.h):
302 * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device
303 * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device
304 * - cmd_ctrl: hardwarespecific function for accesing control-lines
305 * - dev_ready: hardwarespecific function for accesing device ready/busy line
306 * - enable_hwecc?: function to enable (reset) hardware ecc generator. Must
307 * only be provided if a hardware ECC is available
308 * - eccm.ode: mode of ecc, see defines
309 * - chip_delay: chip dependent delay for transfering data from array to
310 * read regs (tR)
311 * - options: various chip options. They can partly be set to inform
312 * nand_scan about special functionality. See the defines for further
313 * explanation
314 * Members with a "?" were not set in the merged testing-NAND branch,
315 * so they are not set here either.
316 */
317 int board_nand_init(struct nand_chip *nand)
318 {
319 #if (LINUX_MACH_TYPE == MACH_TYPE_SEABOARD)
320 /* GPIO port H bit 3, H.03, GMI_AD11->MFG_MODE_R, */
321 tg2_gpio_direction_output(7, 3, 1);
322 #endif
323 #if (LINUX_MACH_TYPE == MACH_TYPE_HARMONY)
324 /* GPIO port C bit 7, C.07, GMI_WP->NAND_WP */
325 tg2_gpio_direction_output(2, 7, 1);
326 #endif
327 nand->cmd_ctrl = tegra2_nand_hwcontrol;
328 nand->dev_ready = tegra2_nand_dev_ready;
329 nand->ecc.mode = NAND_ECC_NONE;
330 nand->ecc.layout = &nand_soft_eccoob;
331 nand->options = LP_OPTIONS;
332 nand->cmdfunc = tegra2_nand_command;
333 nand->read_byte = tegra2_nand_read_byte;
334 nand->read_buf = tegra2_nand_read_buf;
335 nand->write_buf = tegra2_nand_write_buf;
336 return 0;
337 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698