static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *chip = mtd->priv; struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd); u32 mar; if (!(ctrl & fun->last_ctrl)) { fsl_upm_end_pattern(&fun->upm); if (cmd == NAND_CMD_NONE) return; fun->last_ctrl = ctrl & (NAND_ALE | NAND_CLE); } if (ctrl & NAND_CTRL_CHANGE) { if (ctrl & NAND_ALE) fsl_upm_start_pattern(&fun->upm, fun->upm_addr_offset); else if (ctrl & NAND_CLE) fsl_upm_start_pattern(&fun->upm, fun->upm_cmd_offset); } mar = (cmd << (32 - fun->upm.width)) | fun->mchip_offsets[fun->mchip_number]; fsl_upm_run_pattern(&fun->upm, chip->IO_ADDR_R, mar); if (fun->wait_flags & FSL_UPM_WAIT_RUN_PATTERN) fun_wait_rnb(fun); }
static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *chip = mtd->priv; struct fsl_upm_nand *fun = chip->priv; void __iomem *io_addr; u32 mar; if (!(ctrl & fun->last_ctrl)) { fsl_upm_end_pattern(&fun->upm); if (cmd == NAND_CMD_NONE) return; fun->last_ctrl = ctrl & (NAND_ALE | NAND_CLE); } if (ctrl & NAND_CTRL_CHANGE) { if (ctrl & NAND_ALE) fsl_upm_start_pattern(&fun->upm, fun->upm_addr_offset); else if (ctrl & NAND_CLE) fsl_upm_start_pattern(&fun->upm, fun->upm_cmd_offset); } mar = cmd << (32 - fun->width); io_addr = fun->upm.io_addr; #if CONFIG_SYS_NAND_MAX_CHIPS > 1 if (fun->chip_nr > 0) { io_addr += fun->chip_offset * fun->chip_nr; if (fun->upm_mar_chip_offset) mar |= fun->upm_mar_chip_offset * fun->chip_nr; } #endif fsl_upm_run_pattern(&fun->upm, fun->width, io_addr, mar); /* * Some boards/chips needs this. At least the MPC8360E-RDK and * TQM8548 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. */ if (fun->wait_flags & FSL_UPM_WAIT_RUN_PATTERN) fun_wait(fun); }
static void fun_cmdfunc(struct mtd_info *mtd, unsigned command, int column, int page_addr) { 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); } 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); 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); }
static void nand_hwcontrol (struct mtd_info *mtd, int cmd) { struct nand_chip *chip = mtd->priv; struct fsl_upm_nand *fun = chip->priv; 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; } }