diff mbox series

[v2,2/3] mtd: rawnand: qcom: Fix onfi param page read

Message ID 20241122085933.2663927-3-quic_mdalam@quicinc.com
State New
Headers show
Series QPIC v2 fixes for SDX75 | expand

Commit Message

Md Sadre Alam Nov. 22, 2024, 8:59 a.m. UTC
For QPIC V2 onwards there is a separate register to read
last code word "QPIC_NAND_READ_LOCATION_LAST_CW_n".

qcom_param_page_type_exec() is used to read only one code word
If it will get configure number of code words to 1 in QPIC_NAND_DEV0_CFG0
register then QPIC controller thinks its reading the last code word,
since we are having separate register to read the last code word,
we have to configure "QPIC_NAND_READ_LOCATION_LAST_CW_n" register
to fetch data from QPIC buffer to system memory.

Without this change page read was failing with timeout error

/ # hexdump -C /dev/mtd1
[  129.206113] qcom-nandc 1cc8000.nand-controller: failure to read page/oob
hexdump: /dev/mtd1: Connection timed out

This issue only seen on SDX targets since SDX target used QPICv2. But
same working on IPQ targets since IPQ used QPICv1.

Cc: stable@vger.kernel.org
Fixes: 89550beb098e ("mtd: rawnand: qcom: Implement exec_op()")
Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
---

Change in [v2]

* Updated commit message

* Added stable kernel tag

* Replaced the buf_count value of 512 with the len in bytes.

Change in [v1]

* Resolved the issue with reading a single code word in the parameter
  page read

 drivers/mtd/nand/raw/qcom_nandc.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

Comments

Manivannan Sadhasivam Nov. 26, 2024, 5:41 a.m. UTC | #1
On Fri, Nov 22, 2024 at 02:29:32PM +0530, Md Sadre Alam wrote:

Please change subject to:

mtd: rawnand: qcom: Fix last codeword read in qcom_param_page_type_exec()

> For QPIC V2 onwards there is a separate register to read
> last code word "QPIC_NAND_READ_LOCATION_LAST_CW_n".
> 
> qcom_param_page_type_exec() is used to read only one code word
> If it will get configure number of code words to 1 in QPIC_NAND_DEV0_CFG0

"If it configures the number of..."

> register then QPIC controller thinks its reading the last code word,
> since we are having separate register to read the last code word,
> we have to configure "QPIC_NAND_READ_LOCATION_LAST_CW_n" register
> to fetch data from QPIC buffer to system memory.
> 
> Without this change page read was failing with timeout error
> 
> / # hexdump -C /dev/mtd1
> [  129.206113] qcom-nandc 1cc8000.nand-controller: failure to read page/oob
> hexdump: /dev/mtd1: Connection timed out
> 
> This issue only seen on SDX targets since SDX target used QPICv2. But
> same working on IPQ targets since IPQ used QPICv1.
> 
> Cc: stable@vger.kernel.org
> Fixes: 89550beb098e ("mtd: rawnand: qcom: Implement exec_op()")
> Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

- Mani

> ---
> 
> Change in [v2]
> 
> * Updated commit message
> 
> * Added stable kernel tag
> 
> * Replaced the buf_count value of 512 with the len in bytes.
> 
> Change in [v1]
> 
> * Resolved the issue with reading a single code word in the parameter
>   page read
> 
>  drivers/mtd/nand/raw/qcom_nandc.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
> index cc59461df72e..31ec3db1246d 100644
> --- a/drivers/mtd/nand/raw/qcom_nandc.c
> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
> @@ -2859,7 +2859,12 @@ static int qcom_param_page_type_exec(struct nand_chip *chip,  const struct nand_
>  	const struct nand_op_instr *instr = NULL;
>  	unsigned int op_id = 0;
>  	unsigned int len = 0;
> -	int ret;
> +	int ret, reg_base;
> +
> +	reg_base = NAND_READ_LOCATION_0;
> +
> +	if (nandc->props->qpic_v2)
> +		reg_base = NAND_READ_LOCATION_LAST_CW_0;
>  
>  	ret = qcom_parse_instructions(chip, subop, &q_op);
>  	if (ret)
> @@ -2911,7 +2916,10 @@ static int qcom_param_page_type_exec(struct nand_chip *chip,  const struct nand_
>  	op_id = q_op.data_instr_idx;
>  	len = nand_subop_get_data_len(subop, op_id);
>  
> -	nandc_set_read_loc(chip, 0, 0, 0, len, 1);

nandc_set_read_loc() does changes the register offset based on QPIC version. So
what exactly you are trying to fix here?

- Mani

> +	if (nandc->props->qpic_v2)
> +		nandc_set_read_loc_last(chip, reg_base, 0, len, 1);
> +	else
> +		nandc_set_read_loc_first(chip, reg_base, 0, len, 1);
>  
>  	if (!nandc->props->qpic_v2) {
>  		write_reg_dma(nandc, NAND_DEV_CMD_VLD, 1, 0);
> -- 
> 2.34.1
>
Md Sadre Alam Nov. 27, 2024, 9:11 a.m. UTC | #2
On 11/26/2024 11:11 AM, Manivannan Sadhasivam wrote:
> On Fri, Nov 22, 2024 at 02:29:32PM +0530, Md Sadre Alam wrote:
> 
> Please change subject to:
> 
> mtd: rawnand: qcom: Fix last codeword read in qcom_param_page_type_exec()
Ok
> 
>> For QPIC V2 onwards there is a separate register to read
>> last code word "QPIC_NAND_READ_LOCATION_LAST_CW_n".
>>
>> qcom_param_page_type_exec() is used to read only one code word
>> If it will get configure number of code words to 1 in QPIC_NAND_DEV0_CFG0
> 
> "If it configures the number of..."
Ok
> 
>> register then QPIC controller thinks its reading the last code word,
>> since we are having separate register to read the last code word,
>> we have to configure "QPIC_NAND_READ_LOCATION_LAST_CW_n" register
>> to fetch data from QPIC buffer to system memory.
>>
>> Without this change page read was failing with timeout error
>>
>> / # hexdump -C /dev/mtd1
>> [  129.206113] qcom-nandc 1cc8000.nand-controller: failure to read page/oob
>> hexdump: /dev/mtd1: Connection timed out
>>
>> This issue only seen on SDX targets since SDX target used QPICv2. But
>> same working on IPQ targets since IPQ used QPICv1.
>>
>> Cc: stable@vger.kernel.org
>> Fixes: 89550beb098e ("mtd: rawnand: qcom: Implement exec_op()")
>> Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
> 
> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> 
> - Mani
> 
>> ---
>>
>> Change in [v2]
>>
>> * Updated commit message
>>
>> * Added stable kernel tag
>>
>> * Replaced the buf_count value of 512 with the len in bytes.
>>
>> Change in [v1]
>>
>> * Resolved the issue with reading a single code word in the parameter
>>    page read
>>
>>   drivers/mtd/nand/raw/qcom_nandc.c | 12 ++++++++++--
>>   1 file changed, 10 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
>> index cc59461df72e..31ec3db1246d 100644
>> --- a/drivers/mtd/nand/raw/qcom_nandc.c
>> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
>> @@ -2859,7 +2859,12 @@ static int qcom_param_page_type_exec(struct nand_chip *chip,  const struct nand_
>>   	const struct nand_op_instr *instr = NULL;
>>   	unsigned int op_id = 0;
>>   	unsigned int len = 0;
>> -	int ret;
>> +	int ret, reg_base;
>> +
>> +	reg_base = NAND_READ_LOCATION_0;
>> +
>> +	if (nandc->props->qpic_v2)
>> +		reg_base = NAND_READ_LOCATION_LAST_CW_0;
>>   
>>   	ret = qcom_parse_instructions(chip, subop, &q_op);
>>   	if (ret)
>> @@ -2911,7 +2916,10 @@ static int qcom_param_page_type_exec(struct nand_chip *chip,  const struct nand_
>>   	op_id = q_op.data_instr_idx;
>>   	len = nand_subop_get_data_len(subop, op_id);
>>   
>> -	nandc_set_read_loc(chip, 0, 0, 0, len, 1);
> 
> nandc_set_read_loc() does changes the register offset based on QPIC version. So
> what exactly you are trying to fix here?
QPICv2 having separate register to copy last code word data from QPIC buffer to Memory.
e.g for 2K page nand total code word = 4, so to copy first three code word need to configure
NAND_LOCATIONn register , but to copy last code word need to configure NAND_LOCATIONn_LAST
register.
> 
> - Mani
> 
>> +	if (nandc->props->qpic_v2)
>> +		nandc_set_read_loc_last(chip, reg_base, 0, len, 1);
>> +	else
>> +		nandc_set_read_loc_first(chip, reg_base, 0, len, 1);
>>   
>>   	if (!nandc->props->qpic_v2) {
>>   		write_reg_dma(nandc, NAND_DEV_CMD_VLD, 1, 0);
>> -- 
>> 2.34.1
>>
>
diff mbox series

Patch

diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
index cc59461df72e..31ec3db1246d 100644
--- a/drivers/mtd/nand/raw/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -2859,7 +2859,12 @@  static int qcom_param_page_type_exec(struct nand_chip *chip,  const struct nand_
 	const struct nand_op_instr *instr = NULL;
 	unsigned int op_id = 0;
 	unsigned int len = 0;
-	int ret;
+	int ret, reg_base;
+
+	reg_base = NAND_READ_LOCATION_0;
+
+	if (nandc->props->qpic_v2)
+		reg_base = NAND_READ_LOCATION_LAST_CW_0;
 
 	ret = qcom_parse_instructions(chip, subop, &q_op);
 	if (ret)
@@ -2911,7 +2916,10 @@  static int qcom_param_page_type_exec(struct nand_chip *chip,  const struct nand_
 	op_id = q_op.data_instr_idx;
 	len = nand_subop_get_data_len(subop, op_id);
 
-	nandc_set_read_loc(chip, 0, 0, 0, len, 1);
+	if (nandc->props->qpic_v2)
+		nandc_set_read_loc_last(chip, reg_base, 0, len, 1);
+	else
+		nandc_set_read_loc_first(chip, reg_base, 0, len, 1);
 
 	if (!nandc->props->qpic_v2) {
 		write_reg_dma(nandc, NAND_DEV_CMD_VLD, 1, 0);