platform: msm_shared: Improve nand read performance for 9x25 and 9x35

Modify qpic nand and bam drivers to perform a single bam transfer
for each page, instead of each codeword.

CRs-Fixed: 615966
Change-Id: I63cc67c17399059f0e5b70f53acff46bb0e63e9e
diff --git a/platform/msm_shared/bam.c b/platform/msm_shared/bam.c
index 5deaecf..f9593a4 100644
--- a/platform/msm_shared/bam.c
+++ b/platform/msm_shared/bam.c
@@ -271,9 +271,13 @@
 		return;
 	}
 
+	/* bits 0:15 of BAM_P_EVNT_REGn denotes the offset. We read the offset,
+	 * and update the offset to notify BAM HW that new descriptors have been written
+	 */
+	val = readl(BAM_P_EVNT_REGn(bam->pipe[pipe_num].pipe_num, bam->base));
+
 	/* Update the fifo peer offset */
-	val = (num_desc - 1) * BAM_DESC_SIZE;
-	val += bam->pipe[pipe_num].fifo.offset;
+	val += (num_desc) * BAM_DESC_SIZE;
 	val &= (bam->pipe[pipe_num].fifo.size * BAM_DESC_SIZE - 1);
 
 	writel(val, BAM_P_EVNT_REGn(bam->pipe[pipe_num].pipe_num, bam->base));
@@ -282,9 +286,11 @@
 /* Function to read the updates for FIFO offsets.
  * bam : BAM that uses the FIFO.
  * pipe : BAM pipe that uses the FIFO.
- * return : FIFO offset where the next descriptor should be written.
- * Note : S/W maintains the circular properties of the FIFO and updates
- *        the offsets accordingly.
+ * return : void.
+ * Note : As per IPCAT This register denotes the pointer Offset of the first un-Acknowledged Descriptor.
+ *        This register is only used by the Software. After receiving an interrupt, software reads this register
+ *        in order to know what descriptors has been processed. Although being Writable, Software
+ *        should never write to this register.
  */
 void bam_read_offset_update(struct bam_instance *bam, unsigned int pipe_num)
 {
@@ -294,12 +300,6 @@
 	offset &= 0xFFFF;
 
 	dprintf(SPEW, "Offset value is %d \n", offset);
-
-	/* Save the next offset to be written to. */
-		bam->pipe[pipe_num].fifo.current = (struct bam_desc*)
-											((uint32_t)bam->pipe[pipe_num].fifo.head + offset);
-
-	bam->pipe[pipe_num].fifo.offset = offset + BAM_DESC_SIZE ;
 }
 
 /* Function to get the next desc address.
diff --git a/platform/msm_shared/qpic_nand.c b/platform/msm_shared/qpic_nand.c
index 4c7dd6b..65ddc68 100644
--- a/platform/msm_shared/qpic_nand.c
+++ b/platform/msm_shared/qpic_nand.c
@@ -1352,6 +1352,10 @@
 	uint32_t status;
 	uint32_t i;
 	int nand_ret = NANDC_RESULT_SUCCESS;
+	uint8_t flags = 0;
+	uint32_t *cmd_list_temp = NULL;
+
+	uint32_t temp_status = 0;
 	/* UD bytes in last CW is 512 - cws_per_page *4.
 	 * Since each of the CW read earlier reads 4 spare bytes.
 	 */
@@ -1384,6 +1388,8 @@
 	/* Reset and Configure erased CW/page detection controller */
 	qpic_nand_erased_status_reset(ce_array, BAM_DESC_LOCK_FLAG);
 
+	/* Queue up the command and data descriptors for all the codewords in a page
+	 * and do a single bam transfer at the end.*/
 	for (i = 0; i < flash.cws_per_page; i++)
 	{
 		num_cmd_desc = 0;
@@ -1436,7 +1442,7 @@
 							 DATA_PRODUCER_PIPE_INDEX,
 							 (unsigned char *)PA((addr_t)buffer),
 							 DATA_BYTES_IN_IMG_PER_CW,
-							 BAM_DESC_INT_FLAG);
+							 0);
 			num_data_desc++;
 			bam_sys_gen_event(&bam, DATA_PRODUCER_PIPE_INDEX, num_data_desc);
 		}
@@ -1454,39 +1460,57 @@
 							CE_WRITE_TYPE);
 		cmd_list_ptr++;
 
-	/* Enqueue the desc for the above commands */
-	bam_add_one_desc(&bam,
+		/* Enqueue the desc for the above commands */
+		bam_add_one_desc(&bam,
 					 CMD_PIPE_INDEX,
 					 (unsigned char*)cmd_list_ptr_start,
 					 PA((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start),
-					 BAM_DESC_NWD_FLAG | BAM_DESC_CMD_FLAG | BAM_DESC_INT_FLAG);
-	num_cmd_desc++;
+					 BAM_DESC_NWD_FLAG | BAM_DESC_CMD_FLAG);
+		num_cmd_desc++;
 
-	qpic_nand_wait_for_cmd_exec(num_cmd_desc);
+		bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_STATUS, (uint32_t)PA((addr_t)&(flash_sts[i])), CE_READ_TYPE);
+
+		cmd_list_temp = cmd_list_ptr;
+
+		cmd_list_ptr++;
+
+		bam_add_cmd_element(cmd_list_ptr, NAND_BUFFER_STATUS, (uint32_t)PA((addr_t)&(buffer_sts[i])), CE_READ_TYPE);
+		cmd_list_ptr++;
+
+		if (i == flash.cws_per_page - 1)
+		{
+			flags = BAM_DESC_CMD_FLAG | BAM_DESC_UNLOCK_FLAG;
+		}
+		else
+			flags = BAM_DESC_CMD_FLAG;
+
+		/* Enqueue the desc for the above command */
+		bam_add_one_desc(&bam,
+					CMD_PIPE_INDEX,
+					(unsigned char*)PA((addr_t)cmd_list_temp),
+					PA((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_temp),
+					flags);
+		num_cmd_desc++;
+
+		buffer += DATA_BYTES_IN_IMG_PER_CW;
+
+		/* Notify BAM HW about the newly added descriptors */
+		bam_sys_gen_event(&bam, CMD_PIPE_INDEX, num_cmd_desc);
+	}
 
 	qpic_nand_wait_for_data(DATA_PRODUCER_PIPE_INDEX);
 
-	/* Save the status registers. */
-	flash_sts[i] = qpic_nand_read_reg(NAND_FLASH_STATUS, 0, cmd_list_ptr++);
-	buffer_sts[i] = qpic_nand_read_reg(NAND_BUFFER_STATUS, 0, cmd_list_ptr++);
-
-	flash_sts[i] = qpic_nand_check_status(flash_sts[i]);
-
-	buffer += DATA_BYTES_IN_IMG_PER_CW;
-	}
-
-	/* Read the buffer status again so that we can unlock the bam with this desc. */
-	buffer_sts[--i] = qpic_nand_read_reg(NAND_BUFFER_STATUS, BAM_DESC_UNLOCK_FLAG, cmd_list_ptr++);
-
 	/* Check status */
 	for (i = 0; i < flash.cws_per_page ; i ++)
+	{
+		flash_sts[i] = qpic_nand_check_status(flash_sts[i]);
 		if (flash_sts[i])
 		{
 			nand_ret = NANDC_RESULT_BAD_PAGE;
-			dprintf(CRITICAL, "NAND page read failed. page: %x\n", page);
+			dprintf(CRITICAL, "NAND page read failed. page: %x status %x\n", page, flash_sts[i]);
 			goto qpic_nand_read_page_error;
 		}
-
+	}
 qpic_nand_read_page_error:
 return nand_ret;
 }