Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d178e3e8 authored by Baruch Siach's avatar Baruch Siach Committed by David Woodhouse
Browse files

mtd: mxc_nand: add support for multiple chips on V21 devices



Do the following to add support for up to 4 chips on V21 devices (i.MX25 and
i.MX35):

* implement .select_chip for V21
* adjust existing NFC_V1_V2_BUF_ADDR writes to take chip select into account
* unlock all chip selects at preset_v1_v2()
* scan up to 4 devices at .probe

This has been tested on i.MX25 with two attached NAND chip (on one die).

Signed-off-by: default avatarBaruch Siach <baruch@tkos.co.il>
Signed-off-by: default avatarArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent 61c4f2c8
Loading
Loading
Loading
Loading
+32 −19
Original line number Diff line number Diff line
@@ -56,8 +56,14 @@
#define NFC_V1_V2_WRPROT		(host->regs + 0x12)
#define NFC_V1_UNLOCKSTART_BLKADDR	(host->regs + 0x14)
#define NFC_V1_UNLOCKEND_BLKADDR	(host->regs + 0x16)
#define NFC_V21_UNLOCKSTART_BLKADDR	(host->regs + 0x20)
#define NFC_V21_UNLOCKEND_BLKADDR	(host->regs + 0x22)
#define NFC_V21_UNLOCKSTART_BLKADDR0	(host->regs + 0x20)
#define NFC_V21_UNLOCKSTART_BLKADDR1	(host->regs + 0x24)
#define NFC_V21_UNLOCKSTART_BLKADDR2	(host->regs + 0x28)
#define NFC_V21_UNLOCKSTART_BLKADDR3	(host->regs + 0x2c)
#define NFC_V21_UNLOCKEND_BLKADDR0	(host->regs + 0x22)
#define NFC_V21_UNLOCKEND_BLKADDR1	(host->regs + 0x26)
#define NFC_V21_UNLOCKEND_BLKADDR2	(host->regs + 0x2a)
#define NFC_V21_UNLOCKEND_BLKADDR3	(host->regs + 0x2e)
#define NFC_V1_V2_NF_WRPRST		(host->regs + 0x18)
#define NFC_V1_V2_CONFIG1		(host->regs + 0x1a)
#define NFC_V1_V2_CONFIG2		(host->regs + 0x1c)
@@ -152,6 +158,7 @@ struct mxc_nand_host {
	int			clk_act;
	int			irq;
	int			eccsize;
	int			active_cs;

	struct completion	op_completion;

@@ -445,7 +452,7 @@ static void send_page_v1_v2(struct mtd_info *mtd, unsigned int ops)
	for (i = 0; i < bufs; i++) {

		/* NANDFC buffer 0 is used for page read/write */
		writew(i, NFC_V1_V2_BUF_ADDR);
		writew((host->active_cs << 4) | i, NFC_V1_V2_BUF_ADDR);

		writew(ops, NFC_V1_V2_CONFIG2);

@@ -470,7 +477,7 @@ static void send_read_id_v1_v2(struct mxc_nand_host *host)
	struct nand_chip *this = &host->nand;

	/* NANDFC buffer 0 is used for device ID output */
	writew(0x0, NFC_V1_V2_BUF_ADDR);
	writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR);

	writew(NFC_ID, NFC_V1_V2_CONFIG2);

@@ -505,7 +512,7 @@ static uint16_t get_dev_status_v1_v2(struct mxc_nand_host *host)
	uint32_t store;
	uint16_t ret;

	writew(0x0, NFC_V1_V2_BUF_ADDR);
	writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR);

	/*
	 * The device status is stored in main_area0. To
@@ -686,24 +693,24 @@ static void mxc_nand_select_chip(struct mtd_info *mtd, int chip)
	struct nand_chip *nand_chip = mtd->priv;
	struct mxc_nand_host *host = nand_chip->priv;

	switch (chip) {
	case -1:
	if (chip == -1) {
		/* Disable the NFC clock */
		if (host->clk_act) {
			clk_disable(host->clk);
			host->clk_act = 0;
		}
		break;
	case 0:
		/* Enable the NFC clock */
		return;
	}

	if (!host->clk_act) {
		/* Enable the NFC clock */
		clk_enable(host->clk);
		host->clk_act = 1;
	}
		break;

	default:
		break;
	if (nfc_is_v21()) {
		host->active_cs = chip;
		writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR);
	}
}

@@ -834,8 +841,14 @@ static void preset_v1_v2(struct mtd_info *mtd)

	/* Blocks to be unlocked */
	if (nfc_is_v21()) {
		writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR);
		writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR);
		writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR0);
		writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR1);
		writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR2);
		writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR3);
		writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR0);
		writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR1);
		writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR2);
		writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR3);
	} else if (nfc_is_v1()) {
		writew(0x0, NFC_V1_UNLOCKSTART_BLKADDR);
		writew(0x4000, NFC_V1_UNLOCKEND_BLKADDR);
@@ -1200,7 +1213,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
		irq_control_v1_v2(host, 1);

	/* first scan to find the device and get the page size */
	if (nand_scan_ident(mtd, 1, NULL)) {
	if (nand_scan_ident(mtd, nfc_is_v21() ? 4 : 1, NULL)) {
		err = -ENXIO;
		goto escan;
	}