+#ifdef NFC_V3_0
+/*
+ * Do a page read at random address
+ *
+ * @param pg_no page number offset from 0
+ * @param pg_off byte offset within the page
+ * @param ecc_force can force ecc to be off. Otherwise, by default it is on
+ * unless the page offset is non-zero
+ * @param cs_line indicates which NAND of interleaved NAND devices is used
+ *
+ * @return 0 if successful; non-zero otherwise
+ */
+static int nfc_read_pg_random(u32 pg_no, u32 pg_off, u32 ecc_force, u32 cs_line, u32 num_of_chips)
+{
+ u32 ecc = NFC_FLASH_CONFIG2_ECC_EN;
+ u32 v, res = 0;
+ int i;
+
+ // clear the NAND_STATUS_SUM_REG register
+ nfc_reg_write(0, NAND_STATUS_SUM_REG);
+
+ // the 2nd condition is to test for unaligned page address -- ecc has to be off.
+ if (ecc_force == ECC_FORCE_OFF || pg_off != 0 ) {
+ ecc = 0;
+ }
+
+ // Take care of config1 for RBA and SP_EN
+ v = nfc_reg_read(NAND_CONFIGURATION1_REG) & ~0x71;
+ nfc_reg_write(v, NAND_CONFIGURATION1_REG);
+
+ // For ECC
+ v = nfc_reg_read(NFC_FLASH_CONFIG2_REG) & ~NFC_FLASH_CONFIG2_ECC_EN;
+ // setup config2 register for ECC enable or not
+ write_nfc_ip_reg(v | ecc, NFC_FLASH_CONFIG2_REG);
+
+ start_nfc_addr_ops(FLASH_Read_Mode1, pg_no, pg_off, 0, cs_line, num_of_chips);
+
+ if (g_is_2k_page || g_is_4k_page) {
+ // combine the two commands for 2k/4k page read
+ nfc_reg_write((FLASH_Read_Mode1_LG << 8) | FLASH_Read_Mode1, NAND_CMD_REG);
+ } else {
+ // just one command is enough for 512 page
+ nfc_reg_write(FLASH_Read_Mode1, NAND_CMD_REG);
+ }
+
+ // start auto-read
+ nfc_reg_write(NAND_LAUNCH_AUTO_READ, NAND_LAUNCH_REG);
+ wait_op_done();
+
+ for (i = 1; i < NFC_SPARE_BUF_SZ / 16; i++) {
+ memcpy((void *)(NAND_SPAR_BUF0 + i * 16),
+ (void *)(NAND_SPAR_BUF0 + i * NFC_SPARE_BUF_SZ), 16);
+ }
+ v = nfc_reg_read(NAND_STATUS_SUM_REG);
+ // test for CS0 ECC error from the STATUS_SUM register
+ if ((v & (0x0100 << cs_line)) != 0) {
+ // clear the status
+ nfc_reg_write(v & ~(0x0100 << cs_line), NAND_STATUS_SUM_REG);
+ diag_printf("ECC error from NAND_STATUS_SUM_REG(0x%08lx) = 0x%08x\n",
+ NAND_STATUS_SUM_REG, v);
+ diag_printf("NAND_ECC_STATUS_RESULT_REG(0x%08lx) = 0x%08x\n", NAND_ECC_STATUS_RESULT_REG,
+ nfc_reg_read(NAND_ECC_STATUS_RESULT_REG));
+ res = -1;
+ }
+ return res;
+}
+#else