[PATCH v4 08/20] mtd: nand: qcom: support for passing flags in transfer functions

Abhishek Sahu absahu at codeaurora.org
Wed Aug 16 00:23:33 PDT 2017


On 2017-08-16 09:48, Archit Taneja wrote:
> On 08/11/2017 05:09 PM, Abhishek Sahu wrote:
>> The BAM has multiple flags to control the transfer. This patch
>> adds flags parameter in register and data transfer functions and
>> modifies all these functions call with appropriate flags using
>> following rule
>> 
>> 1. Read and write can’t go in single command descriptor so
>>     separate SGL should be used.
>> 2. For some of the requests, NWD flag should be set in BAM
>>     DMA descriptor.
>> 3. For Data write, the BAM has internal buffer for each codeword.
>>     All write request will modify the data in internal buffer and
>>     this buffer will be flushed to NAND device once EOT flag is set.
>>     So for all the write requests in single codeword, the EOT should
>>     be cleared for all tx data descriptors except the last one.
>> 
>> Signed-off-by: Abhishek Sahu <absahu at codeaurora.org>
>> ---
>>   drivers/mtd/nand/qcom_nandc.c | 122 
>> ++++++++++++++++++++++++------------------
>>   1 file changed, 70 insertions(+), 52 deletions(-)
>> 
>> diff --git a/drivers/mtd/nand/qcom_nandc.c 
>> b/drivers/mtd/nand/qcom_nandc.c
>> index f52a692..d9c8a6b 100644
>> --- a/drivers/mtd/nand/qcom_nandc.c
>> +++ b/drivers/mtd/nand/qcom_nandc.c
>> @@ -180,6 +180,14 @@
>>   #define QPIC_PER_CW_CMD_SGL		32
>>   #define QPIC_PER_CW_DATA_SGL		8
>>   +/* Flags used for BAM DMA desc preparation*/

  We can remove BAM from here since later on
  we will pass flag for erase code word and it will
  be used by ADM also.

>> +/* Don't set the EOT in current tx sgl */
>> +#define NAND_BAM_NO_EOT			BIT(0)
>> +/* Set the NWD flag in current sgl */
>> +#define NAND_BAM_NWD			BIT(1)
>> +/* Finish writing in the current sgl and start writing in another sgl 
>> */
>> +#define NAND_BAM_NEXT_SGL		BIT(2)
>> +
>>   /*
>>    * This data type corresponds to the BAM transaction which will be 
>> used for all
>>    * NAND transfers.
>> @@ -731,7 +739,7 @@ static int prep_adm_dma_desc(struct 
>> qcom_nand_controller *nandc, bool read,
>>    * @num_regs:		number of registers to read
> 
> Minor comment: the read_reg_dma/write_reg/read_data/write_data_dma
> funcs add a new arg, so it
> would be nice to update the comment describing the function and its
> arguments. It would also

  Thanks. I will update the comment to include this new arg.

> be nice to mention that the flags are presently used only for
> controllers using BAM.
> 

  We can use this flag for ADM also so I will make the
  comment generic.

> With that,
> 
> Reviewed-by: Archit Taneja <architt at codeaurora.org>
> 
> Thanks,
> Archit
> 
>>    */
>>   static int read_reg_dma(struct qcom_nand_controller *nandc, int 
>> first,
>> -			int num_regs)
>> +			int num_regs, unsigned int flags)
>>   {
>>   	bool flow_control = false;
>>   	void *vaddr;
>> @@ -755,7 +763,7 @@ static int read_reg_dma(struct 
>> qcom_nand_controller *nandc, int first,
>>    * @num_regs:		number of registers to write
>>    */
>>   static int write_reg_dma(struct qcom_nand_controller *nandc, int 
>> first,
>> -			 int num_regs)
>> +			 int num_regs, unsigned int flags)
>>   {
>>   	bool flow_control = false;
>>   	struct nandc_regs *regs = nandc->regs;
>> @@ -767,6 +775,9 @@ static int write_reg_dma(struct 
>> qcom_nand_controller *nandc, int first,
>>   	if (first == NAND_FLASH_CMD)
>>   		flow_control = true;
>>   +	if (first == NAND_EXEC_CMD)
>> +		flags |= NAND_BAM_NWD;
>> +
>>   	if (first == NAND_DEV_CMD1_RESTORE)
>>   		first = NAND_DEV_CMD1;
>>   @@ -788,7 +799,7 @@ static int write_reg_dma(struct 
>> qcom_nand_controller *nandc, int first,
>>    * @size:		DMA transaction size in bytes
>>    */
>>   static int read_data_dma(struct qcom_nand_controller *nandc, int 
>> reg_off,
>> -			 const u8 *vaddr, int size)
>> +			 const u8 *vaddr, int size, unsigned int flags)
>>   {
>>   	return prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false);
>>   }
>> @@ -802,7 +813,7 @@ static int read_data_dma(struct 
>> qcom_nand_controller *nandc, int reg_off,
>>    * @size:		DMA transaction size in bytes
>>    */
>>   static int write_data_dma(struct qcom_nand_controller *nandc, int 
>> reg_off,
>> -			  const u8 *vaddr, int size)
>> +			  const u8 *vaddr, int size, unsigned int flags)
>>   {
>>   	return prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, 
>> false);
>>   }
>> @@ -813,9 +824,9 @@ static int write_data_dma(struct 
>> qcom_nand_controller *nandc, int reg_off,
>>    */
>>   static void config_nand_page_read(struct qcom_nand_controller 
>> *nandc)
>>   {
>> -	write_reg_dma(nandc, NAND_ADDR0, 2);
>> -	write_reg_dma(nandc, NAND_DEV0_CFG0, 3);
>> -	write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1);
>> +	write_reg_dma(nandc, NAND_ADDR0, 2, 0);
>> +	write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0);
>> +	write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1, 0);
>>   }
>>     /*
>> @@ -824,11 +835,12 @@ static void config_nand_page_read(struct 
>> qcom_nand_controller *nandc)
>>    */
>>   static void config_nand_cw_read(struct qcom_nand_controller *nandc)
>>   {
>> -	write_reg_dma(nandc, NAND_FLASH_CMD, 1);
>> -	write_reg_dma(nandc, NAND_EXEC_CMD, 1);
>> +	write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
>> +	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
>>   -	read_reg_dma(nandc, NAND_FLASH_STATUS, 2);
>> -	read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1);
>> +	read_reg_dma(nandc, NAND_FLASH_STATUS, 2, 0);
>> +	read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1,
>> +		     NAND_BAM_NEXT_SGL);
>>   }
>>     /*
>> @@ -847,9 +859,10 @@ static void 
>> config_nand_single_cw_page_read(struct qcom_nand_controller *nandc)
>>    */
>>   static void config_nand_page_write(struct qcom_nand_controller 
>> *nandc)
>>   {
>> -	write_reg_dma(nandc, NAND_ADDR0, 2);
>> -	write_reg_dma(nandc, NAND_DEV0_CFG0, 3);
>> -	write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1);
>> +	write_reg_dma(nandc, NAND_ADDR0, 2, 0);
>> +	write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0);
>> +	write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1,
>> +		      NAND_BAM_NEXT_SGL);
>>   }
>>     /*
>> @@ -858,13 +871,13 @@ static void config_nand_page_write(struct 
>> qcom_nand_controller *nandc)
>>    */
>>   static void config_nand_cw_write(struct qcom_nand_controller *nandc)
>>   {
>> -	write_reg_dma(nandc, NAND_FLASH_CMD, 1);
>> -	write_reg_dma(nandc, NAND_EXEC_CMD, 1);
>> +	write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
>> +	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
>>   -	read_reg_dma(nandc, NAND_FLASH_STATUS, 1);
>> +	read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
>>   -	write_reg_dma(nandc, NAND_FLASH_STATUS, 1);
>> -	write_reg_dma(nandc, NAND_READ_STATUS, 1);
>> +	write_reg_dma(nandc, NAND_FLASH_STATUS, 1, 0);
>> +	write_reg_dma(nandc, NAND_READ_STATUS, 1, NAND_BAM_NEXT_SGL);
>>   }
>>     /*
>> @@ -911,8 +924,8 @@ static int nandc_param(struct qcom_nand_host 
>> *host)
>>   	nandc_set_reg(nandc, NAND_DEV_CMD1_RESTORE, nandc->cmd1);
>>   	nandc_set_reg(nandc, NAND_DEV_CMD_VLD_RESTORE, nandc->vld);
>>   -	write_reg_dma(nandc, NAND_DEV_CMD_VLD, 1);
>> -	write_reg_dma(nandc, NAND_DEV_CMD1, 1);
>> +	write_reg_dma(nandc, NAND_DEV_CMD_VLD, 1, 0);
>> +	write_reg_dma(nandc, NAND_DEV_CMD1, 1, NAND_BAM_NEXT_SGL);
>>     	nandc->buf_count = 512;
>>   	memset(nandc->data_buffer, 0xff, nandc->buf_count);
>> @@ -920,11 +933,11 @@ static int nandc_param(struct qcom_nand_host 
>> *host)
>>   	config_nand_single_cw_page_read(nandc);
>>     	read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer,
>> -		      nandc->buf_count);
>> +		      nandc->buf_count, 0);
>>     	/* restore CMD1 and VLD regs */
>> -	write_reg_dma(nandc, NAND_DEV_CMD1_RESTORE, 1);
>> -	write_reg_dma(nandc, NAND_DEV_CMD_VLD_RESTORE, 1);
>> +	write_reg_dma(nandc, NAND_DEV_CMD1_RESTORE, 1, 0);
>> +	write_reg_dma(nandc, NAND_DEV_CMD_VLD_RESTORE, 1, 
>> NAND_BAM_NEXT_SGL);
>>     	return 0;
>>   }
>> @@ -946,14 +959,14 @@ static int erase_block(struct qcom_nand_host 
>> *host, int page_addr)
>>   	nandc_set_reg(nandc, NAND_FLASH_STATUS, host->clrflashstatus);
>>   	nandc_set_reg(nandc, NAND_READ_STATUS, host->clrreadstatus);
>>   -	write_reg_dma(nandc, NAND_FLASH_CMD, 3);
>> -	write_reg_dma(nandc, NAND_DEV0_CFG0, 2);
>> -	write_reg_dma(nandc, NAND_EXEC_CMD, 1);
>> +	write_reg_dma(nandc, NAND_FLASH_CMD, 3, NAND_BAM_NEXT_SGL);
>> +	write_reg_dma(nandc, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL);
>> +	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
>>   -	read_reg_dma(nandc, NAND_FLASH_STATUS, 1);
>> +	read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
>>   -	write_reg_dma(nandc, NAND_FLASH_STATUS, 1);
>> -	write_reg_dma(nandc, NAND_READ_STATUS, 1);
>> +	write_reg_dma(nandc, NAND_FLASH_STATUS, 1, 0);
>> +	write_reg_dma(nandc, NAND_READ_STATUS, 1, NAND_BAM_NEXT_SGL);
>>     	return 0;
>>   }
>> @@ -973,10 +986,10 @@ static int read_id(struct qcom_nand_host *host, 
>> int column)
>>   	nandc_set_reg(nandc, NAND_FLASH_CHIP_SELECT, DM_EN);
>>   	nandc_set_reg(nandc, NAND_EXEC_CMD, 1);
>>   -	write_reg_dma(nandc, NAND_FLASH_CMD, 4);
>> -	write_reg_dma(nandc, NAND_EXEC_CMD, 1);
>> +	write_reg_dma(nandc, NAND_FLASH_CMD, 4, NAND_BAM_NEXT_SGL);
>> +	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
>>   -	read_reg_dma(nandc, NAND_READ_ID, 1);
>> +	read_reg_dma(nandc, NAND_READ_ID, 1, NAND_BAM_NEXT_SGL);
>>     	return 0;
>>   }
>> @@ -990,10 +1003,10 @@ static int reset(struct qcom_nand_host *host)
>>   	nandc_set_reg(nandc, NAND_FLASH_CMD, RESET_DEVICE);
>>   	nandc_set_reg(nandc, NAND_EXEC_CMD, 1);
>>   -	write_reg_dma(nandc, NAND_FLASH_CMD, 1);
>> -	write_reg_dma(nandc, NAND_EXEC_CMD, 1);
>> +	write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
>> +	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
>>   -	read_reg_dma(nandc, NAND_FLASH_STATUS, 1);
>> +	read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
>>     	return 0;
>>   }
>> @@ -1389,7 +1402,7 @@ static int read_page_ecc(struct qcom_nand_host 
>> *host, u8 *data_buf,
>>     		if (data_buf)
>>   			read_data_dma(nandc, FLASH_BUF_ACC, data_buf,
>> -				      data_size);
>> +				      data_size, 0);
>>     		/*
>>   		 * when ecc is enabled, the controller doesn't read the real
>> @@ -1405,7 +1418,7 @@ static int read_page_ecc(struct qcom_nand_host 
>> *host, u8 *data_buf,
>>   				*oob_buf++ = 0xff;
>>     			read_data_dma(nandc, FLASH_BUF_ACC + data_size,
>> -				      oob_buf, oob_size);
>> +				      oob_buf, oob_size, 0);
>>   		}
>>     		if (data_buf)
>> @@ -1447,7 +1460,7 @@ static int copy_last_cw(struct qcom_nand_host 
>> *host, int page)
>>     	config_nand_single_cw_page_read(nandc);
>>   -	read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, size);
>> +	read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, size, 0);
>>     	ret = submit_descs(nandc);
>>   	if (ret)
>> @@ -1516,19 +1529,19 @@ static int qcom_nandc_read_page_raw(struct 
>> mtd_info *mtd,
>>     		config_nand_cw_read(nandc);
>>   -		read_data_dma(nandc, reg_off, data_buf, data_size1);
>> +		read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
>>   		reg_off += data_size1;
>>   		data_buf += data_size1;
>>   -		read_data_dma(nandc, reg_off, oob_buf, oob_size1);
>> +		read_data_dma(nandc, reg_off, oob_buf, oob_size1, 0);
>>   		reg_off += oob_size1;
>>   		oob_buf += oob_size1;
>>   -		read_data_dma(nandc, reg_off, data_buf, data_size2);
>> +		read_data_dma(nandc, reg_off, data_buf, data_size2, 0);
>>   		reg_off += data_size2;
>>   		data_buf += data_size2;
>>   -		read_data_dma(nandc, reg_off, oob_buf, oob_size2);
>> +		read_data_dma(nandc, reg_off, oob_buf, oob_size2, 0);
>>   		oob_buf += oob_size2;
>>   	}
>>   @@ -1595,7 +1608,8 @@ static int qcom_nandc_write_page(struct 
>> mtd_info *mtd, struct nand_chip *chip,
>>   		}
>>     -		write_data_dma(nandc, FLASH_BUF_ACC, data_buf, data_size);
>> +		write_data_dma(nandc, FLASH_BUF_ACC, data_buf, data_size,
>> +			       i == (ecc->steps - 1) ? NAND_BAM_NO_EOT : 0);
>>     		/*
>>   		 * when ECC is enabled, we don't really need to write anything
>> @@ -1608,7 +1622,7 @@ static int qcom_nandc_write_page(struct mtd_info 
>> *mtd, struct nand_chip *chip,
>>   			oob_buf += host->bbm_size;
>>     			write_data_dma(nandc, FLASH_BUF_ACC + data_size,
>> -				       oob_buf, oob_size);
>> +				       oob_buf, oob_size, 0);
>>   		}
>>     		config_nand_cw_write(nandc);
>> @@ -1663,19 +1677,22 @@ static int qcom_nandc_write_page_raw(struct 
>> mtd_info *mtd,
>>   			oob_size2 = host->ecc_bytes_hw + host->spare_bytes;
>>   		}
>>   -		write_data_dma(nandc, reg_off, data_buf, data_size1);
>> +		write_data_dma(nandc, reg_off, data_buf, data_size1,
>> +			       NAND_BAM_NO_EOT);
>>   		reg_off += data_size1;
>>   		data_buf += data_size1;
>>   -		write_data_dma(nandc, reg_off, oob_buf, oob_size1);
>> +		write_data_dma(nandc, reg_off, oob_buf, oob_size1,
>> +			       NAND_BAM_NO_EOT);
>>   		reg_off += oob_size1;
>>   		oob_buf += oob_size1;
>>   -		write_data_dma(nandc, reg_off, data_buf, data_size2);
>> +		write_data_dma(nandc, reg_off, data_buf, data_size2,
>> +			       NAND_BAM_NO_EOT);
>>   		reg_off += data_size2;
>>   		data_buf += data_size2;
>>   -		write_data_dma(nandc, reg_off, oob_buf, oob_size2);
>> +		write_data_dma(nandc, reg_off, oob_buf, oob_size2, 0);
>>   		oob_buf += oob_size2;
>>     		config_nand_cw_write(nandc);
>> @@ -1729,8 +1746,8 @@ static int qcom_nandc_write_oob(struct mtd_info 
>> *mtd, struct nand_chip *chip,
>>   	update_rw_regs(host, 1, false);
>>     	config_nand_page_write(nandc);
>> -	write_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer,
>> -		       data_size + oob_size);
>> +	write_data_dma(nandc, FLASH_BUF_ACC,
>> +		       nandc->data_buffer, data_size + oob_size, 0);
>>   	config_nand_cw_write(nandc);
>>     	ret = submit_descs(nandc);
>> @@ -1814,7 +1831,8 @@ static int qcom_nandc_block_markbad(struct 
>> mtd_info *mtd, loff_t ofs)
>>   	update_rw_regs(host, 1, false);
>>     	config_nand_page_write(nandc);
>> -	write_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, 
>> host->cw_size);
>> +	write_data_dma(nandc, FLASH_BUF_ACC,
>> +		       nandc->data_buffer, host->cw_size, 0);
>>   	config_nand_cw_write(nandc);
>>     	ret = submit_descs(nandc);
>> 



More information about the linux-mtd mailing list