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

Commit e9aa671f authored by Boris Brezillon's avatar Boris Brezillon
Browse files

mtd: nand: sunxi: improve ->cmd_ctrl() function



Try to pack address and command cycles into a single NAND controller
command to avoid polling the status register for each single change
on the NAND bus.

Signed-off-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
parent fe82ccef
Loading
Loading
Loading
Loading
+44 −8
Original line number Diff line number Diff line
@@ -238,6 +238,10 @@ struct sunxi_nand_chip {
	u32 timing_cfg;
	u32 timing_ctl;
	int selected;
	int addr_cycles;
	u32 addr[2];
	int cmd_cycles;
	u8 cmd[2];
	int nsels;
	struct sunxi_nand_chip_sel sels[0];
};
@@ -525,19 +529,51 @@ static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
		writel(tmp, nfc->regs + NFC_REG_CTL);
	}

	if (dat == NAND_CMD_NONE)
	if (dat == NAND_CMD_NONE && (ctrl & NAND_NCE) &&
	    !(ctrl & (NAND_CLE | NAND_ALE))) {
		u32 cmd = 0;

		if (!sunxi_nand->addr_cycles && !sunxi_nand->cmd_cycles)
			return;

	if (ctrl & NAND_CLE) {
		writel(NFC_SEND_CMD1 | dat, nfc->regs + NFC_REG_CMD);
	} else {
		writel(dat, nfc->regs + NFC_REG_ADDR_LOW);
		writel(NFC_SEND_ADR, nfc->regs + NFC_REG_CMD);
		if (sunxi_nand->cmd_cycles--)
			cmd |= NFC_SEND_CMD1 | sunxi_nand->cmd[0];

		if (sunxi_nand->cmd_cycles--) {
			cmd |= NFC_SEND_CMD2;
			writel(sunxi_nand->cmd[1],
			       nfc->regs + NFC_REG_RCMD_SET);
		}

		sunxi_nand->cmd_cycles = 0;

		if (sunxi_nand->addr_cycles) {
			cmd |= NFC_SEND_ADR |
			       NFC_ADR_NUM(sunxi_nand->addr_cycles);
			writel(sunxi_nand->addr[0],
			       nfc->regs + NFC_REG_ADDR_LOW);
		}

		if (sunxi_nand->addr_cycles > 4)
			writel(sunxi_nand->addr[1],
			       nfc->regs + NFC_REG_ADDR_HIGH);

		writel(cmd, nfc->regs + NFC_REG_CMD);
		sunxi_nand->addr[0] = 0;
		sunxi_nand->addr[1] = 0;
		sunxi_nand->addr_cycles = 0;
		sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
	}

	if (ctrl & NAND_CLE) {
		sunxi_nand->cmd[sunxi_nand->cmd_cycles++] = dat;
	} else if (ctrl & NAND_ALE) {
		sunxi_nand->addr[sunxi_nand->addr_cycles / 4] |=
				dat << ((sunxi_nand->addr_cycles % 4) * 8);
		sunxi_nand->addr_cycles++;
	}
}

/* These seed values have been extracted from Allwinner's BSP */
static const u16 sunxi_nfc_randomizer_page_seeds[] = {
	0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72,