[][mtd: mtk-snand: add more nfi status check]

[Description]
Add extra NFI status check after interrupt done for read/write
operations of mtk-snand driver

[Release-log]
N/A

Change-Id: I0f126cfdca3b34db4c0c30239416bcf73e68f2fb
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/4553306
diff --git a/target/linux/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand.c b/target/linux/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand.c
index 6d57d56..922454d 100644
--- a/target/linux/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand.c
+++ b/target/linux/mediatek/files-5.4/drivers/mtd/mtk-snand/mtk-snand.c
@@ -57,8 +57,15 @@
 #define FIFO_WR_REMAIN_S		8
 #define FIFO_RD_REMAIN_S		0
 
+#define NFI_ADDRCNTR			0x070
+#define SEC_CNTR			GENMASK(16, 12)
+#define	SEC_CNTR_S			12
+
 #define NFI_STRADDR			0x080
 
+#define NFI_BYTELEN			0x084
+#define	BUS_SEC_CNTR(val)		(((val) & SEC_CNTR) >> SEC_CNTR_S)
+
 #define NFI_FDM0L			0x0a0
 #define NFI_FDM0M			0x0a4
 #define NFI_FDML(n)			(NFI_FDM0L + (n) * 8)
@@ -715,7 +722,7 @@
 
 static int mtk_snand_read_cache(struct mtk_snand *snf, uint32_t page, bool raw)
 {
-	uint32_t coladdr, rwbytes, mode, len;
+	uint32_t coladdr, rwbytes, mode, len, val;
 	uintptr_t dma_addr;
 	int ret;
 
@@ -783,6 +790,26 @@
 		goto cleanup;
 	}
 
+	/* Wait for BUS_SEC_CNTR returning expected value */
+	ret = read32_poll_timeout(snf->nfi_base + NFI_BYTELEN, val,
+				  BUS_SEC_CNTR(val) >= snf->ecc_steps,
+				  0, SNFI_POLL_INTERVAL);
+	if (ret) {
+		snand_log_nfi(snf->pdev,
+			      "Timed out waiting for BUS_SEC_CNTR\n");
+		goto cleanup;
+	}
+
+	/* Wait for bus becoming idle */
+	ret = read32_poll_timeout(snf->nfi_base + NFI_MASTERSTA, val,
+				  !(val & snf->nfi_soc->mastersta_mask),
+				  0, SNFI_POLL_INTERVAL);
+	if (ret) {
+		snand_log_nfi(snf->pdev,
+			      "Timed out waiting for bus becoming idle\n");
+		goto cleanup;
+	}
+
 	if (!raw) {
 		ret = mtk_ecc_wait_decoder_done(snf);
 		if (ret)
@@ -941,7 +968,7 @@
 static int mtk_snand_program_load(struct mtk_snand *snf, uint32_t page,
 				  bool raw)
 {
-	uint32_t coladdr, rwbytes, mode, len;
+	uint32_t coladdr, rwbytes, mode, len, val;
 	uintptr_t dma_addr;
 	int ret;
 
@@ -1011,6 +1038,16 @@
 		goto cleanup;
 	}
 
+	/* Wait for BUS_SEC_CNTR returning expected value */
+	ret = read32_poll_timeout(snf->nfi_base + NFI_BYTELEN, val,
+				  BUS_SEC_CNTR(val) >= snf->ecc_steps,
+				  0, SNFI_POLL_INTERVAL);
+	if (ret) {
+		snand_log_nfi(snf->pdev,
+			      "Timed out waiting for BUS_SEC_CNTR\n");
+		goto cleanup;
+	}
+
 	if (!raw)
 		mtk_snand_ecc_encoder_stop(snf);