[U-Boot-Users] [PATCH] NAND FSL UPM: driver re-write using the hwcontrol callback

NAND FSL UPM: driver re-write using the hwcontrol callback
This is a re-write of the NAND FSL UPM driver using the more universal hwcontrol callback (instead of the cmdfunc callback). Here is a brief list of furher modifications:
- For the time being, the UPM setup writing the UPM array has been removed from the driver and must now be done by the board specific code.
- The bus width definition in "struct fsl_upm_nand" is now in bits to comply with the corresponding Linux driver.
- chip->dev_read is only set if fun->dev_ready != NULL, which is required for boards not connecting the R/B pin.
- A few issue have been fixed with MxMR bit manipulation like in the corresponding Linux driver.
Note: I think the "io_addr" field of "struct fsl_upm" could be removed as well, because the address is already determined by "nand->IO_ADDR_[RW]", but I'm not 100% sure.
This patch has been tested on a TQM8548 modules with the NAND chip Micron MT29F8G08FABWP.
This patch is based on the following patches posted to this list a few minutes ago:
[PATCH] PPC: add accessor macros to clear and set bits in one shot [PATCH] 83xx/85xx/86xx: add more MxMR local bus definitions
Anton, could you please verify if it works on your MPC8360ERDK board as well. A patch will follow. In principle, the NAND driver of the TQM8272 should work with it as well.
Signed-off-by: Wolfgang Grandegger wg@grandegger.com --- drivers/mtd/nand/fsl_upm.c | 133 +++++++++++++++++--------------------------- include/linux/mtd/fsl_upm.h | 1 2 files changed, 52 insertions(+), 82 deletions(-)
Index: u-boot/drivers/mtd/nand/fsl_upm.c =================================================================== --- u-boot.orig/drivers/mtd/nand/fsl_upm.c +++ u-boot/drivers/mtd/nand/fsl_upm.c @@ -20,112 +20,89 @@ #include <linux/mtd/fsl_upm.h> #include <nand.h>
-#define FSL_UPM_MxMR_OP_NO (0 << 28) /* normal operation */ -#define FSL_UPM_MxMR_OP_WA (1 << 28) /* write array */ -#define FSL_UPM_MxMR_OP_RA (2 << 28) /* read array */ -#define FSL_UPM_MxMR_OP_RP (3 << 28) /* run pattern */ +static int fsl_upm_in_pattern;
static void fsl_upm_start_pattern(struct fsl_upm *upm, u32 pat_offset) { - out_be32(upm->mxmr, FSL_UPM_MxMR_OP_RP | pat_offset); + clrsetbits_be32(upm->mxmr, MxMR_MAD_MSK, MxMR_OP_RUNP | pat_offset); }
static void fsl_upm_end_pattern(struct fsl_upm *upm) { - out_be32(upm->mxmr, FSL_UPM_MxMR_OP_NO); - while (in_be32(upm->mxmr) != FSL_UPM_MxMR_OP_NO) + clrbits32(upm->mxmr, MxMR_OP_RUNP); + + while (in_be32(upm->mxmr) & MxMR_OP_RUNP) eieio(); }
static void fsl_upm_run_pattern(struct fsl_upm *upm, int width, u32 cmd) { - out_be32(upm->mar, cmd << (32 - width * 8)); - out_8(upm->io_addr, 0x0); -} - -static void fsl_upm_setup(struct fsl_upm *upm) -{ - int i; - - /* write upm array */ - out_be32(upm->mxmr, FSL_UPM_MxMR_OP_WA); - - for (i = 0; i < 64; i++) { - out_be32(upm->mdr, upm->array[i]); + out_be32(upm->mar, cmd << (32 - width)); + switch (width) { + case 8: out_8(upm->io_addr, 0x0); + break; + case 16: + out_be16(upm->io_addr, 0x0); + break; + case 32: + out_be32(upm->io_addr, 0x0); + break; } - - /* normal operation */ - out_be32(upm->mxmr, FSL_UPM_MxMR_OP_NO); - while (in_be32(upm->mxmr) != FSL_UPM_MxMR_OP_NO) - eieio(); }
-static void fun_cmdfunc(struct mtd_info *mtd, unsigned command, int column, - int page_addr) +static void nand_hwcontrol (struct mtd_info *mtd, int cmd) { struct nand_chip *chip = mtd->priv; struct fsl_upm_nand *fun = chip->priv;
- fsl_upm_start_pattern(&fun->upm, fun->upm_cmd_offset); - - if (command == NAND_CMD_SEQIN) { - int readcmd; - - if (column >= mtd->oobblock) { - /* OOB area */ - column -= mtd->oobblock; - readcmd = NAND_CMD_READOOB; - } else if (column < 256) { - /* First 256 bytes --> READ0 */ - readcmd = NAND_CMD_READ0; - } else { - column -= 256; - readcmd = NAND_CMD_READ1; - } - fsl_upm_run_pattern(&fun->upm, fun->width, readcmd); + switch (cmd) { + case NAND_CTL_SETCLE: + fsl_upm_start_pattern(&fun->upm, fun->upm_cmd_offset); + fsl_upm_in_pattern++; + break; + case NAND_CTL_SETALE: + fsl_upm_start_pattern(&fun->upm, fun->upm_addr_offset); + fsl_upm_in_pattern++; + break; + case NAND_CTL_CLRCLE: + case NAND_CTL_CLRALE: + fsl_upm_end_pattern(&fun->upm); + fsl_upm_in_pattern--; + break; } +#if 1 + /* Temorary check */ + if (fsl_upm_in_pattern < 0 || fsl_upm_in_pattern > 1) + printf("fsl_upm: Oops, unexpected fsl_upm_in_pattern %d\n", + fsl_upm_in_pattern); +#endif +}
- fsl_upm_run_pattern(&fun->upm, fun->width, command); - - fsl_upm_end_pattern(&fun->upm); - - fsl_upm_start_pattern(&fun->upm, fun->upm_addr_offset); - - if (column != -1) - fsl_upm_run_pattern(&fun->upm, fun->width, column); +static void nand_write_byte(struct mtd_info *mtd, u_char byte) +{ + struct nand_chip *chip = mtd->priv;
- if (page_addr != -1) { - fsl_upm_run_pattern(&fun->upm, fun->width, page_addr); - fsl_upm_run_pattern(&fun->upm, fun->width, - (page_addr >> 8) & 0xFF); - if (chip->chipsize > (32 << 20)) { - fsl_upm_run_pattern(&fun->upm, fun->width, - (page_addr >> 16) & 0x0f); - } - } + if (fsl_upm_in_pattern) { + struct fsl_upm_nand *fun = chip->priv;
- fsl_upm_end_pattern(&fun->upm); + fsl_upm_run_pattern(&fun->upm, fun->width, byte);
- if (fun->wait_pattern) { /* * Some boards/chips needs this. At least on MPC8360E-RDK we * need it. Probably weird chip, because I don't see any need * for this on MPC8555E + Samsung K9F1G08U0A. Usually here are * 0-2 unexpected busy states per block read. */ - while (!fun->dev_ready()) - debug("unexpected busy state\n"); + if (fun->wait_pattern) { + while (!fun->dev_ready()) + debug("unexpected busy state\n"); + } + } else { + out_8(chip->IO_ADDR_W, byte); } }
-static void nand_write_byte(struct mtd_info *mtd, u_char byte) -{ - struct nand_chip *chip = mtd->priv; - - out_8(chip->IO_ADDR_W, byte); -} - static u8 nand_read_byte(struct mtd_info *mtd) { struct nand_chip *chip = mtd->priv; @@ -164,10 +141,6 @@ static int nand_verify_buf(struct mtd_in return 0; }
-static void nand_hwcontrol(struct mtd_info *mtd, int cmd) -{ -} - static int nand_dev_ready(struct mtd_info *mtd) { struct nand_chip *chip = mtd->priv; @@ -179,22 +152,20 @@ static int nand_dev_ready(struct mtd_inf int fsl_upm_nand_init(struct nand_chip *chip, struct fsl_upm_nand *fun) { /* yet only 8 bit accessors implemented */ - if (fun->width != 1) + if (fun->width != 8 && fun->width != 16 && fun->width != 32) return -ENOSYS;
- fsl_upm_setup(&fun->upm); - chip->priv = fun; chip->chip_delay = fun->chip_delay; chip->eccmode = NAND_ECC_SOFT; - chip->cmdfunc = fun_cmdfunc; chip->hwcontrol = nand_hwcontrol; chip->read_byte = nand_read_byte; chip->read_buf = nand_read_buf; chip->write_byte = nand_write_byte; chip->write_buf = nand_write_buf; chip->verify_buf = nand_verify_buf; - chip->dev_ready = nand_dev_ready; + if (fun->dev_ready) + chip->dev_ready = nand_dev_ready;
return 0; } Index: u-boot/include/linux/mtd/fsl_upm.h =================================================================== --- u-boot.orig/include/linux/mtd/fsl_upm.h +++ u-boot/include/linux/mtd/fsl_upm.h @@ -16,7 +16,6 @@ #include <linux/mtd/nand.h>
struct fsl_upm { - const u32 *array; void __iomem *mdr; void __iomem *mxmr; void __iomem *mar;

On Mon, Jun 02, 2008 at 12:11:11PM +0200, Wolfgang Grandegger wrote:
NAND FSL UPM: driver re-write using the hwcontrol callback
This is a re-write of the NAND FSL UPM driver using the more universal hwcontrol callback (instead of the cmdfunc callback). Here is a brief list of furher modifications:
For the time being, the UPM setup writing the UPM array has been removed from the driver and must now be done by the board specific code.
The bus width definition in "struct fsl_upm_nand" is now in bits to comply with the corresponding Linux driver.
chip->dev_read is only set if fun->dev_ready != NULL, which is required for boards not connecting the R/B pin.
A few issue have been fixed with MxMR bit manipulation like in the corresponding Linux driver.
Note: I think the "io_addr" field of "struct fsl_upm" could be removed as well, because the address is already determined by "nand->IO_ADDR_[RW]", but I'm not 100% sure.
This patch has been tested on a TQM8548 modules with the NAND chip Micron MT29F8G08FABWP.
This patch is based on the following patches posted to this list a few minutes ago:
[PATCH] PPC: add accessor macros to clear and set bits in one shot [PATCH] 83xx/85xx/86xx: add more MxMR local bus definitions
Anton, could you please verify if it works on your MPC8360ERDK board as well. A patch will follow. In principle, the NAND driver of the TQM8272 should work with it as well.
Works great here (tested on MPC8360E-RDK). Thanks!
Signed-off-by: Wolfgang Grandegger wg@grandegger.com
Acked-by: Anton Vorontsov avorontsov@ru.mvista.com

Anton Vorontsov wrote:
On Mon, Jun 02, 2008 at 12:11:11PM +0200, Wolfgang Grandegger wrote:
NAND FSL UPM: driver re-write using the hwcontrol callback
This is a re-write of the NAND FSL UPM driver using the more universal hwcontrol callback (instead of the cmdfunc callback). Here is a brief list of furher modifications:
For the time being, the UPM setup writing the UPM array has been removed from the driver and must now be done by the board specific code.
The bus width definition in "struct fsl_upm_nand" is now in bits to comply with the corresponding Linux driver.
chip->dev_read is only set if fun->dev_ready != NULL, which is required for boards not connecting the R/B pin.
A few issue have been fixed with MxMR bit manipulation like in the corresponding Linux driver.
Note: I think the "io_addr" field of "struct fsl_upm" could be removed as well, because the address is already determined by "nand->IO_ADDR_[RW]", but I'm not 100% sure.
This patch has been tested on a TQM8548 modules with the NAND chip Micron MT29F8G08FABWP.
This patch is based on the following patches posted to this list a few minutes ago:
[PATCH] PPC: add accessor macros to clear and set bits in one shot [PATCH] 83xx/85xx/86xx: add more MxMR local bus definitions
Anton, could you please verify if it works on your MPC8360ERDK board as well. A patch will follow. In principle, the NAND driver of the TQM8272 should work with it as well.
Works great here (tested on MPC8360E-RDK). Thanks!
Great.
Signed-off-by: Wolfgang Grandegger wg@grandegger.com
Acked-by: Anton Vorontsov avorontsov@ru.mvista.com
All 4 patches are maintained by different people. What is the fastest way to get these patches in? Maybe Stefan could pick them up directly?
Wolfgang.

On Monday 02 June 2008, Wolfgang Grandegger wrote:
Signed-off-by: Wolfgang Grandegger wg@grandegger.com
Acked-by: Anton Vorontsov avorontsov@ru.mvista.com
All 4 patches are maintained by different people. What is the fastest way to get these patches in? Maybe Stefan could pick them up directly?
No. I can't. Simply because it's not my responsibility anymore. :)
Scott Wood is now the custodian for NAND FLASH stuff. So he will probably pick it up. Scott?
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de =====================================================================

Stefan Roese wrote:
On Monday 02 June 2008, Wolfgang Grandegger wrote:
Signed-off-by: Wolfgang Grandegger wg@grandegger.com
Acked-by: Anton Vorontsov avorontsov@ru.mvista.com
All 4 patches are maintained by different people. What is the fastest way to get these patches in? Maybe Stefan could pick them up directly?
No. I can't. Simply because it's not my responsibility anymore. :)
Ah, right, no I remember. At http://www.denx.de/wiki/UBoot/Custodians and http://git.denx.de/?p=u-boot.git;a=forks you are still listed as the owner of u-boot-nand-flash.git.
Scott Wood is now the custodian for NAND FLASH stuff. So he will
probably pick
it up. Scott?
That would be nice.
Wolfgang.

Hi,
Stefan Roese wrote:
On Monday 02 June 2008, Wolfgang Grandegger wrote:
Signed-off-by: Wolfgang Grandegger wg@grandegger.com
Acked-by: Anton Vorontsov avorontsov@ru.mvista.com
All 4 patches are maintained by different people. What is the fastest way to get these patches in? Maybe Stefan could pick them up directly?
No. I can't. Simply because it's not my responsibility anymore. :)
Ah, right, no I remember. At http://www.denx.de/wiki/UBoot/Custodians and http://git.denx.de/?p=u-boot.git;a=forks you are still listed as the owner of u-boot-nand-flash.git.
At least the first is a wiki :-P
Anyway, changed.
Cheers Detlev

On Mon, Jun 02, 2008 at 12:11:11PM +0200, Wolfgang Grandegger wrote:
NAND FSL UPM: driver re-write using the hwcontrol callback
This is a re-write of the NAND FSL UPM driver using the more universal hwcontrol callback (instead of the cmdfunc callback). Here is a brief list of furher modifications:
[snip]
This patch is based on the following patches posted to this list a few minutes ago:
[PATCH] PPC: add accessor macros to clear and set bits in one shot [PATCH] 83xx/85xx/86xx: add more MxMR local bus definitions
[snip]
/* yet only 8 bit accessors implemented */
- if (fun->width != 1)
- if (fun->width != 8 && fun->width != 16 && fun->width != 32)
The above comment looks like it should be removed.
Otherwise, Acked-by: Scott Wood scottwood@freescale.com
Feel free to send via a powerpc tree due to the dependencies.
-Scott
participants (5)
-
Anton Vorontsov
-
Detlev Zundel
-
Scott Wood
-
Stefan Roese
-
Wolfgang Grandegger