aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBen Dooks <ben@simtec.co.uk>2005-03-17 06:31:30 -0500
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-05-23 06:55:50 -0400
commit3e4ef3bb77f7b87c631ba188d4a4b4eb30b2f16f (patch)
tree3ca45d8f929bf85f79036d8419519073f79b9d0b /drivers
parent09c7933547e383ab89ee1b08ec86899bef3035cf (diff)
[MTD] NAND s3c2410: Simplify command handling
Updated with tglx's suggestion to simply the command invocation by simply changing the address of the IO write area Signed-off-by: Ben Dooks <ben@simtec.co.uk> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/nand/s3c2410.c118
1 files changed, 12 insertions, 106 deletions
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index cb04b3c771e4..64b1d95e3e37 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -11,9 +11,10 @@
11 * 23-Sep-2004 BJD Mulitple device support 11 * 23-Sep-2004 BJD Mulitple device support
12 * 28-Sep-2004 BJD Fixed ECC placement for Hardware mode 12 * 28-Sep-2004 BJD Fixed ECC placement for Hardware mode
13 * 12-Oct-2004 BJD Fixed errors in use of platform data 13 * 12-Oct-2004 BJD Fixed errors in use of platform data
14 * 18-Feb-2004 BJD Fix sparse errors 14 * 18-Feb-2005 BJD Fix sparse errors
15 * 14-Mar-2005 BJD Applied tglx's code reduction patch
15 * 16 *
16 * $Id: s3c2410.c,v 1.8 2005/02/18 14:46:12 bjd Exp $ 17 * $Id: s3c2410.c,v 1.12 2005/03/17 11:31:26 bjd Exp $
17 * 18 *
18 * This program is free software; you can redistribute it and/or modify 19 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by 20 * it under the terms of the GNU General Public License as published by
@@ -236,6 +237,7 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
236static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd) 237static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd)
237{ 238{
238 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 239 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
240 struct nand_chip *chip = mtd->priv;
239 unsigned long cur; 241 unsigned long cur;
240 242
241 switch (cmd) { 243 switch (cmd) {
@@ -251,117 +253,22 @@ static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd)
251 writel(cur, info->regs + S3C2410_NFCONF); 253 writel(cur, info->regs + S3C2410_NFCONF);
252 break; 254 break;
253 255
254 /* we don't need to implement these */
255 case NAND_CTL_SETCLE: 256 case NAND_CTL_SETCLE:
256 case NAND_CTL_CLRCLE: 257 chip->IO_ADDR_W = info->regs + S3C2410_NFCMD;
257 case NAND_CTL_SETALE:
258 case NAND_CTL_CLRALE:
259 pr_debug(PFX "s3c2410_nand_hwcontrol(%d) unusedn", cmd);
260 break; 258 break;
261 }
262}
263
264/* s3c2410_nand_command
265 *
266 * This function implements sending commands and the relevant address
267 * information to the chip, via the hardware controller. Since the
268 * S3C2410 generates the correct ALE/CLE signaling automatically, we
269 * do not need to use hwcontrol.
270*/
271
272static void s3c2410_nand_command (struct mtd_info *mtd, unsigned command,
273 int column, int page_addr)
274{
275 register struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
276 register struct nand_chip *this = mtd->priv;
277
278 /*
279 * Write out the command to the device.
280 */
281 if (command == NAND_CMD_SEQIN) {
282 int readcmd;
283
284 if (column >= mtd->oobblock) {
285 /* OOB area */
286 column -= mtd->oobblock;
287 readcmd = NAND_CMD_READOOB;
288 } else if (column < 256) {
289 /* First 256 bytes --> READ0 */
290 readcmd = NAND_CMD_READ0;
291 } else {
292 column -= 256;
293 readcmd = NAND_CMD_READ1;
294 }
295
296 writeb(readcmd, info->regs + S3C2410_NFCMD);
297 }
298 writeb(command, info->regs + S3C2410_NFCMD);
299
300 /* Set ALE and clear CLE to start address cycle */
301 259
302 if (column != -1 || page_addr != -1) { 260 case NAND_CTL_SETALE:
261 chip->IO_ADDR_W = info->regs + S3C2410_NFADDR;
262 break;
303 263
304 /* Serially input address */ 264 /* NAND_CTL_CLRCLE: */
305 if (column != -1) { 265 /* NAND_CTL_CLRALE: */
306 /* Adjust columns for 16 bit buswidth */
307 if (this->options & NAND_BUSWIDTH_16)
308 column >>= 1;
309 writeb(column, info->regs + S3C2410_NFADDR);
310 }
311 if (page_addr != -1) {
312 writeb((unsigned char) (page_addr), info->regs + S3C2410_NFADDR);
313 writeb((unsigned char) (page_addr >> 8), info->regs + S3C2410_NFADDR);
314 /* One more address cycle for higher density devices */
315 if (this->chipsize & 0x0c000000)
316 writeb((unsigned char) ((page_addr >> 16) & 0x0f),
317 info->regs + S3C2410_NFADDR);
318 }
319 /* Latch in address */
320 }
321
322 /*
323 * program and erase have their own busy handlers
324 * status and sequential in needs no delay
325 */
326 switch (command) {
327
328 case NAND_CMD_PAGEPROG:
329 case NAND_CMD_ERASE1:
330 case NAND_CMD_ERASE2:
331 case NAND_CMD_SEQIN:
332 case NAND_CMD_STATUS:
333 return;
334
335 case NAND_CMD_RESET:
336 if (this->dev_ready)
337 break;
338
339 udelay(this->chip_delay);
340 writeb(NAND_CMD_STATUS, info->regs + S3C2410_NFCMD);
341
342 while ( !(this->read_byte(mtd) & 0x40));
343 return;
344
345 /* This applies to read commands */
346 default: 266 default:
347 /* 267 chip->IO_ADDR_W = info->regs + S3C2410_NFDATA;
348 * If we don't have access to the busy pin, we apply the given 268 break;
349 * command delay
350 */
351 if (!this->dev_ready) {
352 udelay (this->chip_delay);
353 return;
354 }
355 } 269 }
356
357 /* Apply this short delay always to ensure that we do wait tWB in
358 * any case on any machine. */
359 ndelay (100);
360 /* wait until command is processed */
361 while (!this->dev_ready(mtd));
362} 270}
363 271
364
365/* s3c2410_nand_devready() 272/* s3c2410_nand_devready()
366 * 273 *
367 * returns 0 if the nand is busy, 1 if it is ready 274 * returns 0 if the nand is busy, 1 if it is ready
@@ -529,7 +436,6 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
529 chip->IO_ADDR_W = info->regs + S3C2410_NFDATA; 436 chip->IO_ADDR_W = info->regs + S3C2410_NFDATA;
530 chip->hwcontrol = s3c2410_nand_hwcontrol; 437 chip->hwcontrol = s3c2410_nand_hwcontrol;
531 chip->dev_ready = s3c2410_nand_devready; 438 chip->dev_ready = s3c2410_nand_devready;
532 chip->cmdfunc = s3c2410_nand_command;
533 chip->write_buf = s3c2410_nand_write_buf; 439 chip->write_buf = s3c2410_nand_write_buf;
534 chip->read_buf = s3c2410_nand_read_buf; 440 chip->read_buf = s3c2410_nand_read_buf;
535 chip->select_chip = s3c2410_nand_select_chip; 441 chip->select_chip = s3c2410_nand_select_chip;