Пример #1
0
/*
  *The TMIO controller converts an 8-bit NAND interface to a 16-bit
  *bus interface, so all data reads and writes must be 16-bit wide.
  *Thus, we implement 16-bit versions of the read, write, and verify
  *buffer functions.
 */
static void
tmio_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
{
	struct tmio_nand *tmio = mtd_to_tmio(mtd);

	tmio_iowrite16_rep(tmio->fcr + FCR_DATA, buf, len >> 1);
}
Пример #2
0
/*
  *The TMIO core has a RDYREQ interrupt on the posedge of #SMRB.
  *This interrupt is normally disabled, but for long operations like
  *erase and write, we enable it to wake us up.  The irq handler
  *disables the interrupt.
 */
static int
tmio_nand_wait(struct mtd_info *mtd, struct nand_chip *nand_chip)
{
	struct tmio_nand *tmio = mtd_to_tmio(mtd);
	long timeout;

	/* enable RDYREQ interrupt */
	tmio_iowrite8(0x0f, tmio->fcr + FCR_ISR);
	tmio_iowrite8(0x81, tmio->fcr + FCR_IMR);

	timeout = wait_event_timeout(nand_chip->controller->wq,
		tmio_nand_dev_ready(mtd),
		msecs_to_jiffies(nand_chip->state == FL_ERASING ? 400 : 20));

	if (unlikely(!tmio_nand_dev_ready(mtd))) {
		tmio_iowrite8(0x00, tmio->fcr + FCR_IMR);
		dev_warn(&tmio->dev->dev, "still busy with %s after %d ms\n",
			nand_chip->state == FL_ERASING ? "erase" : "program",
			nand_chip->state == FL_ERASING ? 400 : 20);

	} else if (unlikely(!timeout)) {
		tmio_iowrite8(0x00, tmio->fcr + FCR_IMR);
		dev_warn(&tmio->dev->dev, "timeout waiting for interrupt\n");
	}

	nand_chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
	return nand_chip->read_byte(mtd);
}
Пример #3
0
static void tmio_nand_hwcontrol(struct mtd_info *mtd, int cmd,
				   unsigned int ctrl)
{
	struct tmio_nand *tmio = mtd_to_tmio(mtd);
	struct nand_chip *chip = mtd->priv;

	if (ctrl & NAND_CTRL_CHANGE) {
		u8 mode;

		if (ctrl & NAND_NCE) {
			mode = FCR_MODE_DATA;

			if (ctrl & NAND_CLE)
				mode |=  FCR_MODE_CLE;
			else
				mode &= ~FCR_MODE_CLE;

			if (ctrl & NAND_ALE)
				mode |=  FCR_MODE_ALE;
			else
				mode &= ~FCR_MODE_ALE;
		} else {
			mode = FCR_MODE_STANDBY;
		}

		tmio_iowrite8(mode, tmio->fcr + FCR_MODE);
		tmio->read_good = 0;
	}

	if (cmd != NAND_CMD_NONE)
		tmio_iowrite8(cmd, chip->IO_ADDR_W);
}
Пример #4
0
static void tmio_nand_enable_hwecc(struct mtd_info *mtd, int mode)
{
	struct tmio_nand *tmio = mtd_to_tmio(mtd);

	tmio_iowrite8(FCR_MODE_HWECC_RESET, tmio->fcr + FCR_MODE);
	tmio_ioread8(tmio->fcr + FCR_DATA);	/* dummy read */
	tmio_iowrite8(FCR_MODE_HWECC_CALC, tmio->fcr + FCR_MODE);
}
Пример #5
0
static int
tmio_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
{
	struct tmio_nand *tmio = mtd_to_tmio(mtd);
	u16				*p = (u16 *) buf;

	for (len >>= 1; len; len--)
		if (*(p++) != tmio_ioread16(tmio->fcr + FCR_DATA))
			return -EFAULT;
	return 0;
}
Пример #6
0
/*
  *The TMIO controller combines two 8-bit data bytes into one 16-bit
  *word. This function separates them so nand_base.c works as expected,
  *especially its NAND_CMD_READID routines.
 *
  *To prevent stale data from being read, tmio_nand_hwcontrol() clears
  *tmio->read_good.
 */
static u_char tmio_nand_read_byte(struct mtd_info *mtd)
{
	struct tmio_nand *tmio = mtd_to_tmio(mtd);
	unsigned int data;

	if (tmio->read_good--)
		return tmio->read;

	data = tmio_ioread16(tmio->fcr + FCR_DATA);
	tmio->read = data >> 8;
	return data;
}
Пример #7
0
static int tmio_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
							u_char *ecc_code)
{
	struct tmio_nand *tmio = mtd_to_tmio(mtd);
	unsigned int ecc;

	tmio_iowrite8(FCR_MODE_HWECC_RESULT, tmio->fcr + FCR_MODE);

	ecc = tmio_ioread16(tmio->fcr + FCR_DATA);
	ecc_code[1] = ecc;	/* 000-255 LP7-0 */
	ecc_code[0] = ecc >> 8;	/* 000-255 LP15-8 */
	ecc = tmio_ioread16(tmio->fcr + FCR_DATA);
	ecc_code[2] = ecc;	/* 000-255 CP5-0,11b */
	ecc_code[4] = ecc >> 8;	/* 256-511 LP7-0 */
	ecc = tmio_ioread16(tmio->fcr + FCR_DATA);
	ecc_code[3] = ecc;	/* 256-511 LP15-8 */
	ecc_code[5] = ecc >> 8;	/* 256-511 CP5-0,11b */

	tmio_iowrite8(FCR_MODE_DATA, tmio->fcr + FCR_MODE);
	return 0;
}
Пример #8
0
static void tmio_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
{
	struct tmio_nand *tmio = mtd_to_tmio(mtd);

	tmio_ioread16_rep(tmio->fcr + FCR_DATA, buf, len >> 1);
}
Пример #9
0
static int tmio_nand_dev_ready(struct mtd_info *mtd)
{
	struct tmio_nand *tmio = mtd_to_tmio(mtd);

	return !(tmio_ioread8(tmio->fcr + FCR_STATUS) & FCR_STATUS_BUSY);
}