From: Cyrille Pitchen <cyrille.pitchen@atmel.com>
To: Marek Vasut <marex@denx.de>
Cc: <nicolas.ferre@atmel.com>, <broonie@kernel.org>,
<linux-spi@vger.kernel.org>, <dwmw2@infradead.org>,
<computersforpeace@gmail.com>, <zajec5@gmail.com>,
<beanhuo@micron.com>, <juhosg@openwrt.org>,
<shijie.huang@intel.com>, <ben@decadent.org.uk>,
<linux-kernel@vger.kernel.org>,
<linux-arm-kernel@lists.infradead.org>,
<devicetree@vger.kernel.org>, <robh+dt@kernel.org>,
<pawel.moll@arm.com>, <mark.rutland@arm.com>,
<ijc+devicetree@hellion.org.uk>, <galak@codeaurora.org>,
<linux-mtd@lists.infradead.org>
Subject: Re: [PATCH linux-next v4 3/5] mtd: spi-nor: allow to tune the number of dummy cycles
Date: Mon, 24 Aug 2015 18:42:46 +0200 [thread overview]
Message-ID: <55DB4986.1000207@atmel.com> (raw)
In-Reply-To: <201508241248.17466.marex@denx.de>
Hi Marek,
Le 24/08/2015 12:48, Marek Vasut a écrit :
> On Monday, August 24, 2015 at 12:13:58 PM, Cyrille Pitchen wrote:
>> The number of dummy cycles used during Fast Read commands can be reduced
>> to improve transfer performances. Each manufacturer has a dedicated set of
>> registers to provide the memory with the exact number of dummy cycles it
>> should expect. Both the memory and the (Q)SPI controller must agree on
>> this number of dummy cycles.
>>
>> The number of dummy cycles can be found into the memory datasheet and
>> mostly depends on the SPI clock frequency, the Fast Read op code and the
>> Single/Dual Data Rate mode.
>>
>> Probing JEDEC Serial Flash Discoverable Parameters (SFDP) tables would
>> only provide the driver with a high enough number of dummy cycles for each
>> Fast Read command to be used for all clock frequencies: this solution
>> would not be optimized.
>>
>> Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
>
> Hi!
>
>> drivers/mtd/spi-nor/spi-nor.c | 97
>> ++++++++++++++++++++++++++++++++++--------- include/linux/mtd/spi-nor.h
>> | 2 +
>> 2 files changed, 80 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
>> index e2a6029dc056..869e098a6841 100644
>> --- a/drivers/mtd/spi-nor/spi-nor.c
>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>> @@ -119,24 +119,6 @@ static int read_cr(struct spi_nor *nor)
>> }
>>
>> /*
>> - * Dummy Cycle calculation for different type of read.
>> - * It can be used to support more commands with
>> - * different dummy cycle requirements.
>> - */
>> -static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
>> -{
>> - switch (nor->flash_read) {
>> - case SPI_NOR_FAST:
>> - case SPI_NOR_DUAL:
>> - case SPI_NOR_QUAD:
>> - return 8;
>> - case SPI_NOR_NORMAL:
>> - return 0;
>> - }
>> - return 0;
>> -}
>
> You can probably just soup up this function so that it sets the
> nor->read_dummy, no ?
>
Actually, this is what the patch does: spi_nor_read_dummy_cycles() was reused
and enhanced few lines below where you've pointed out the
"switch (nor->flash_read)" block should be move after the else block.
I think when I wrote the code I've chosen to move the definition of this
function instead of adding forward declarations of functions such as read_cr()
or write_sr_cr(), which are now called by micron_set_dummy_cycles().
>> -/*
>> * Write status register 1 byte
>> * Returns negative if error occurred.
>> */
>> @@ -1012,6 +994,81 @@ static int set_quad_mode(struct spi_nor *nor, struct
>> flash_info *info) }
>> }
>>
>> +static int micron_set_dummy_cycles(struct spi_nor *nor)
>> +{
>> + int ret;
>> + u8 val, mask;
>> +
>> + /* read the Volatile Configuration Register (VCR) */
>
> NIT: If this is a sentence, start it with capital letter and end it with
> fullstop :)
>
done for the next version
>> + ret = nor->read_reg(nor, SPINOR_OP_RD_VCR, &val, 1);
>> + if (ret < 0) {
>> + dev_err(nor->dev, "error %d reading VCR\n", ret);
>> + return ret;
>> + }
>> +
>> + write_enable(nor);
>> +
>> + /* update the number of dummy into the VCR */
>
> DTTO
>
done for the next version
>> + mask = GENMASK(7, 4);
>> + val &= ~mask;
>> + val |= (nor->read_dummy << 4) & mask;
>> + ret = nor->write_reg(nor, SPINOR_OP_WR_VCR, &val, 1, 0);
>> + if (ret < 0) {
>> + dev_err(nor->dev, "error while writing VCR register\n");
>> + return ret;
>> + }
>> +
>> + ret = spi_nor_wait_till_ready(nor);
>> + if (ret)
>> + return ret;
>> +
>> + return 0;
>> +}
>> +
>> +/*
>> + * Dummy Cycle calculation for different type of read.
>> + * It can be used to support more commands with
>> + * different dummy cycle requirements.
>> + */
>> +static int spi_nor_read_dummy_cycles(struct spi_nor *nor,
>> + const struct flash_info *info)
>> +{
>> + struct device_node *np = nor->dev->of_node;
>> + u32 num_dummy_cycles;
>> +
>> + if (np && !of_property_read_u32(np, "m25p,num-dummy-cycles",
>> + &num_dummy_cycles)) {
>> + nor->read_dummy = num_dummy_cycles;
>> +
>> + /*
>> + * This switch block might be moved after the if...then...else
>> + * statement but it was not tested with all Spansion or Micron
>> + * memories.
>> + * Now the "m25p,num-dummy-cycles" property needs to be
>> + * explicitly set in the device tree so the switch statement is
>> + * executed. This should avoid unwanted side effects and keep
>> + * backward compatibility.
>> + */
>> + switch (JEDEC_MFR(info)) {
>> + case CFI_MFR_ST:
>> + return micron_set_dummy_cycles(nor);
>> + default:
>
> If you do have m25p,num-dummy-cycles set for non-micron flash, you have a
> problem here I believe.
>
>> + break;
>> + }
>> + } else {
>
> The solution would be to drop this else {} bit here, so that if you fail in
> the DT-based configuration, you fall back to this old behavior. What do you
> think please ? :)
>
Good idea!
I also add a trace for the default case of "switch (JEDEC_MFR(info))":
dev_warn(dev, "can't set the number of dummy cycles\n");
So the user is notified that the driver could not use the value of
"m25p,num-dummy-cycles" from the DT before falling back to the legacy
code.
>> + switch (nor->flash_read) {
>> + case SPI_NOR_FAST:
>> + case SPI_NOR_DUAL:
>> + case SPI_NOR_QUAD:
>> + nor->read_dummy = 8;
>> + case SPI_NOR_NORMAL:
>> + nor->read_dummy = 0;
>> + }
>> + }
>> +
>> + return 0;
>> +}
>
> [...]
>
thanks for the review!
Best regards,
Cyrille
WARNING: multiple messages have this Message-ID (diff)
From: Cyrille Pitchen <cyrille.pitchen-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>
To: Marek Vasut <marex-ynQEQJNshbs@public.gmane.org>
Cc: <nicolas.ferre-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>,
<broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
<linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
<dwmw2-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>,
<computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
<zajec5-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
<beanhuo-AL4WhLSQfzjQT0dZR+AlfA@public.gmane.org>,
<juhosg-p3rKhJxN3npAfugRpC6u6w@public.gmane.org>,
<shijie.huang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
<ben-/+tVBieCtBitmTQ+vhA3Yw@public.gmane.org>,
<linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
<linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org>,
<devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
<robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
<pawel.moll-5wv7dgnIgG8@public.gmane.org>,
<mark.rutland-5wv7dgnIgG8@public.gmane.org>,
<ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg@public.gmane.org>,
<galak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>,
<linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org>
Subject: Re: [PATCH linux-next v4 3/5] mtd: spi-nor: allow to tune the number of dummy cycles
Date: Mon, 24 Aug 2015 18:42:46 +0200 [thread overview]
Message-ID: <55DB4986.1000207@atmel.com> (raw)
In-Reply-To: <201508241248.17466.marex-ynQEQJNshbs@public.gmane.org>
Hi Marek,
Le 24/08/2015 12:48, Marek Vasut a écrit :
> On Monday, August 24, 2015 at 12:13:58 PM, Cyrille Pitchen wrote:
>> The number of dummy cycles used during Fast Read commands can be reduced
>> to improve transfer performances. Each manufacturer has a dedicated set of
>> registers to provide the memory with the exact number of dummy cycles it
>> should expect. Both the memory and the (Q)SPI controller must agree on
>> this number of dummy cycles.
>>
>> The number of dummy cycles can be found into the memory datasheet and
>> mostly depends on the SPI clock frequency, the Fast Read op code and the
>> Single/Dual Data Rate mode.
>>
>> Probing JEDEC Serial Flash Discoverable Parameters (SFDP) tables would
>> only provide the driver with a high enough number of dummy cycles for each
>> Fast Read command to be used for all clock frequencies: this solution
>> would not be optimized.
>>
>> Signed-off-by: Cyrille Pitchen <cyrille.pitchen-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>
>
> Hi!
>
>> drivers/mtd/spi-nor/spi-nor.c | 97
>> ++++++++++++++++++++++++++++++++++--------- include/linux/mtd/spi-nor.h
>> | 2 +
>> 2 files changed, 80 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
>> index e2a6029dc056..869e098a6841 100644
>> --- a/drivers/mtd/spi-nor/spi-nor.c
>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>> @@ -119,24 +119,6 @@ static int read_cr(struct spi_nor *nor)
>> }
>>
>> /*
>> - * Dummy Cycle calculation for different type of read.
>> - * It can be used to support more commands with
>> - * different dummy cycle requirements.
>> - */
>> -static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
>> -{
>> - switch (nor->flash_read) {
>> - case SPI_NOR_FAST:
>> - case SPI_NOR_DUAL:
>> - case SPI_NOR_QUAD:
>> - return 8;
>> - case SPI_NOR_NORMAL:
>> - return 0;
>> - }
>> - return 0;
>> -}
>
> You can probably just soup up this function so that it sets the
> nor->read_dummy, no ?
>
Actually, this is what the patch does: spi_nor_read_dummy_cycles() was reused
and enhanced few lines below where you've pointed out the
"switch (nor->flash_read)" block should be move after the else block.
I think when I wrote the code I've chosen to move the definition of this
function instead of adding forward declarations of functions such as read_cr()
or write_sr_cr(), which are now called by micron_set_dummy_cycles().
>> -/*
>> * Write status register 1 byte
>> * Returns negative if error occurred.
>> */
>> @@ -1012,6 +994,81 @@ static int set_quad_mode(struct spi_nor *nor, struct
>> flash_info *info) }
>> }
>>
>> +static int micron_set_dummy_cycles(struct spi_nor *nor)
>> +{
>> + int ret;
>> + u8 val, mask;
>> +
>> + /* read the Volatile Configuration Register (VCR) */
>
> NIT: If this is a sentence, start it with capital letter and end it with
> fullstop :)
>
done for the next version
>> + ret = nor->read_reg(nor, SPINOR_OP_RD_VCR, &val, 1);
>> + if (ret < 0) {
>> + dev_err(nor->dev, "error %d reading VCR\n", ret);
>> + return ret;
>> + }
>> +
>> + write_enable(nor);
>> +
>> + /* update the number of dummy into the VCR */
>
> DTTO
>
done for the next version
>> + mask = GENMASK(7, 4);
>> + val &= ~mask;
>> + val |= (nor->read_dummy << 4) & mask;
>> + ret = nor->write_reg(nor, SPINOR_OP_WR_VCR, &val, 1, 0);
>> + if (ret < 0) {
>> + dev_err(nor->dev, "error while writing VCR register\n");
>> + return ret;
>> + }
>> +
>> + ret = spi_nor_wait_till_ready(nor);
>> + if (ret)
>> + return ret;
>> +
>> + return 0;
>> +}
>> +
>> +/*
>> + * Dummy Cycle calculation for different type of read.
>> + * It can be used to support more commands with
>> + * different dummy cycle requirements.
>> + */
>> +static int spi_nor_read_dummy_cycles(struct spi_nor *nor,
>> + const struct flash_info *info)
>> +{
>> + struct device_node *np = nor->dev->of_node;
>> + u32 num_dummy_cycles;
>> +
>> + if (np && !of_property_read_u32(np, "m25p,num-dummy-cycles",
>> + &num_dummy_cycles)) {
>> + nor->read_dummy = num_dummy_cycles;
>> +
>> + /*
>> + * This switch block might be moved after the if...then...else
>> + * statement but it was not tested with all Spansion or Micron
>> + * memories.
>> + * Now the "m25p,num-dummy-cycles" property needs to be
>> + * explicitly set in the device tree so the switch statement is
>> + * executed. This should avoid unwanted side effects and keep
>> + * backward compatibility.
>> + */
>> + switch (JEDEC_MFR(info)) {
>> + case CFI_MFR_ST:
>> + return micron_set_dummy_cycles(nor);
>> + default:
>
> If you do have m25p,num-dummy-cycles set for non-micron flash, you have a
> problem here I believe.
>
>> + break;
>> + }
>> + } else {
>
> The solution would be to drop this else {} bit here, so that if you fail in
> the DT-based configuration, you fall back to this old behavior. What do you
> think please ? :)
>
Good idea!
I also add a trace for the default case of "switch (JEDEC_MFR(info))":
dev_warn(dev, "can't set the number of dummy cycles\n");
So the user is notified that the driver could not use the value of
"m25p,num-dummy-cycles" from the DT before falling back to the legacy
code.
>> + switch (nor->flash_read) {
>> + case SPI_NOR_FAST:
>> + case SPI_NOR_DUAL:
>> + case SPI_NOR_QUAD:
>> + nor->read_dummy = 8;
>> + case SPI_NOR_NORMAL:
>> + nor->read_dummy = 0;
>> + }
>> + }
>> +
>> + return 0;
>> +}
>
> [...]
>
thanks for the review!
Best regards,
Cyrille
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
WARNING: multiple messages have this Message-ID (diff)
From: cyrille.pitchen@atmel.com (Cyrille Pitchen)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH linux-next v4 3/5] mtd: spi-nor: allow to tune the number of dummy cycles
Date: Mon, 24 Aug 2015 18:42:46 +0200 [thread overview]
Message-ID: <55DB4986.1000207@atmel.com> (raw)
In-Reply-To: <201508241248.17466.marex@denx.de>
Hi Marek,
Le 24/08/2015 12:48, Marek Vasut a ?crit :
> On Monday, August 24, 2015 at 12:13:58 PM, Cyrille Pitchen wrote:
>> The number of dummy cycles used during Fast Read commands can be reduced
>> to improve transfer performances. Each manufacturer has a dedicated set of
>> registers to provide the memory with the exact number of dummy cycles it
>> should expect. Both the memory and the (Q)SPI controller must agree on
>> this number of dummy cycles.
>>
>> The number of dummy cycles can be found into the memory datasheet and
>> mostly depends on the SPI clock frequency, the Fast Read op code and the
>> Single/Dual Data Rate mode.
>>
>> Probing JEDEC Serial Flash Discoverable Parameters (SFDP) tables would
>> only provide the driver with a high enough number of dummy cycles for each
>> Fast Read command to be used for all clock frequencies: this solution
>> would not be optimized.
>>
>> Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
>
> Hi!
>
>> drivers/mtd/spi-nor/spi-nor.c | 97
>> ++++++++++++++++++++++++++++++++++--------- include/linux/mtd/spi-nor.h
>> | 2 +
>> 2 files changed, 80 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
>> index e2a6029dc056..869e098a6841 100644
>> --- a/drivers/mtd/spi-nor/spi-nor.c
>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>> @@ -119,24 +119,6 @@ static int read_cr(struct spi_nor *nor)
>> }
>>
>> /*
>> - * Dummy Cycle calculation for different type of read.
>> - * It can be used to support more commands with
>> - * different dummy cycle requirements.
>> - */
>> -static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
>> -{
>> - switch (nor->flash_read) {
>> - case SPI_NOR_FAST:
>> - case SPI_NOR_DUAL:
>> - case SPI_NOR_QUAD:
>> - return 8;
>> - case SPI_NOR_NORMAL:
>> - return 0;
>> - }
>> - return 0;
>> -}
>
> You can probably just soup up this function so that it sets the
> nor->read_dummy, no ?
>
Actually, this is what the patch does: spi_nor_read_dummy_cycles() was reused
and enhanced few lines below where you've pointed out the
"switch (nor->flash_read)" block should be move after the else block.
I think when I wrote the code I've chosen to move the definition of this
function instead of adding forward declarations of functions such as read_cr()
or write_sr_cr(), which are now called by micron_set_dummy_cycles().
>> -/*
>> * Write status register 1 byte
>> * Returns negative if error occurred.
>> */
>> @@ -1012,6 +994,81 @@ static int set_quad_mode(struct spi_nor *nor, struct
>> flash_info *info) }
>> }
>>
>> +static int micron_set_dummy_cycles(struct spi_nor *nor)
>> +{
>> + int ret;
>> + u8 val, mask;
>> +
>> + /* read the Volatile Configuration Register (VCR) */
>
> NIT: If this is a sentence, start it with capital letter and end it with
> fullstop :)
>
done for the next version
>> + ret = nor->read_reg(nor, SPINOR_OP_RD_VCR, &val, 1);
>> + if (ret < 0) {
>> + dev_err(nor->dev, "error %d reading VCR\n", ret);
>> + return ret;
>> + }
>> +
>> + write_enable(nor);
>> +
>> + /* update the number of dummy into the VCR */
>
> DTTO
>
done for the next version
>> + mask = GENMASK(7, 4);
>> + val &= ~mask;
>> + val |= (nor->read_dummy << 4) & mask;
>> + ret = nor->write_reg(nor, SPINOR_OP_WR_VCR, &val, 1, 0);
>> + if (ret < 0) {
>> + dev_err(nor->dev, "error while writing VCR register\n");
>> + return ret;
>> + }
>> +
>> + ret = spi_nor_wait_till_ready(nor);
>> + if (ret)
>> + return ret;
>> +
>> + return 0;
>> +}
>> +
>> +/*
>> + * Dummy Cycle calculation for different type of read.
>> + * It can be used to support more commands with
>> + * different dummy cycle requirements.
>> + */
>> +static int spi_nor_read_dummy_cycles(struct spi_nor *nor,
>> + const struct flash_info *info)
>> +{
>> + struct device_node *np = nor->dev->of_node;
>> + u32 num_dummy_cycles;
>> +
>> + if (np && !of_property_read_u32(np, "m25p,num-dummy-cycles",
>> + &num_dummy_cycles)) {
>> + nor->read_dummy = num_dummy_cycles;
>> +
>> + /*
>> + * This switch block might be moved after the if...then...else
>> + * statement but it was not tested with all Spansion or Micron
>> + * memories.
>> + * Now the "m25p,num-dummy-cycles" property needs to be
>> + * explicitly set in the device tree so the switch statement is
>> + * executed. This should avoid unwanted side effects and keep
>> + * backward compatibility.
>> + */
>> + switch (JEDEC_MFR(info)) {
>> + case CFI_MFR_ST:
>> + return micron_set_dummy_cycles(nor);
>> + default:
>
> If you do have m25p,num-dummy-cycles set for non-micron flash, you have a
> problem here I believe.
>
>> + break;
>> + }
>> + } else {
>
> The solution would be to drop this else {} bit here, so that if you fail in
> the DT-based configuration, you fall back to this old behavior. What do you
> think please ? :)
>
Good idea!
I also add a trace for the default case of "switch (JEDEC_MFR(info))":
dev_warn(dev, "can't set the number of dummy cycles\n");
So the user is notified that the driver could not use the value of
"m25p,num-dummy-cycles" from the DT before falling back to the legacy
code.
>> + switch (nor->flash_read) {
>> + case SPI_NOR_FAST:
>> + case SPI_NOR_DUAL:
>> + case SPI_NOR_QUAD:
>> + nor->read_dummy = 8;
>> + case SPI_NOR_NORMAL:
>> + nor->read_dummy = 0;
>> + }
>> + }
>> +
>> + return 0;
>> +}
>
> [...]
>
thanks for the review!
Best regards,
Cyrille
WARNING: multiple messages have this Message-ID (diff)
From: Cyrille Pitchen <cyrille.pitchen-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>
To: Marek Vasut <marex-ynQEQJNshbs@public.gmane.org>
Cc: nicolas.ferre-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org,
broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
dwmw2-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org,
computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
zajec5-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
beanhuo-AL4WhLSQfzjQT0dZR+AlfA@public.gmane.org,
juhosg-p3rKhJxN3npAfugRpC6u6w@public.gmane.org,
shijie.huang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org,
ben-/+tVBieCtBitmTQ+vhA3Yw@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
pawel.moll-5wv7dgnIgG8@public.gmane.org,
mark.rutland-5wv7dgnIgG8@public.gmane.org,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg@public.gmane.org,
galak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Subject: Re: [PATCH linux-next v4 3/5] mtd: spi-nor: allow to tune the number of dummy cycles
Date: Mon, 24 Aug 2015 18:42:46 +0200 [thread overview]
Message-ID: <55DB4986.1000207@atmel.com> (raw)
In-Reply-To: <201508241248.17466.marex-ynQEQJNshbs@public.gmane.org>
Hi Marek,
Le 24/08/2015 12:48, Marek Vasut a écrit :
> On Monday, August 24, 2015 at 12:13:58 PM, Cyrille Pitchen wrote:
>> The number of dummy cycles used during Fast Read commands can be reduced
>> to improve transfer performances. Each manufacturer has a dedicated set of
>> registers to provide the memory with the exact number of dummy cycles it
>> should expect. Both the memory and the (Q)SPI controller must agree on
>> this number of dummy cycles.
>>
>> The number of dummy cycles can be found into the memory datasheet and
>> mostly depends on the SPI clock frequency, the Fast Read op code and the
>> Single/Dual Data Rate mode.
>>
>> Probing JEDEC Serial Flash Discoverable Parameters (SFDP) tables would
>> only provide the driver with a high enough number of dummy cycles for each
>> Fast Read command to be used for all clock frequencies: this solution
>> would not be optimized.
>>
>> Signed-off-by: Cyrille Pitchen <cyrille.pitchen-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>
>
> Hi!
>
>> drivers/mtd/spi-nor/spi-nor.c | 97
>> ++++++++++++++++++++++++++++++++++--------- include/linux/mtd/spi-nor.h
>> | 2 +
>> 2 files changed, 80 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
>> index e2a6029dc056..869e098a6841 100644
>> --- a/drivers/mtd/spi-nor/spi-nor.c
>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>> @@ -119,24 +119,6 @@ static int read_cr(struct spi_nor *nor)
>> }
>>
>> /*
>> - * Dummy Cycle calculation for different type of read.
>> - * It can be used to support more commands with
>> - * different dummy cycle requirements.
>> - */
>> -static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
>> -{
>> - switch (nor->flash_read) {
>> - case SPI_NOR_FAST:
>> - case SPI_NOR_DUAL:
>> - case SPI_NOR_QUAD:
>> - return 8;
>> - case SPI_NOR_NORMAL:
>> - return 0;
>> - }
>> - return 0;
>> -}
>
> You can probably just soup up this function so that it sets the
> nor->read_dummy, no ?
>
Actually, this is what the patch does: spi_nor_read_dummy_cycles() was reused
and enhanced few lines below where you've pointed out the
"switch (nor->flash_read)" block should be move after the else block.
I think when I wrote the code I've chosen to move the definition of this
function instead of adding forward declarations of functions such as read_cr()
or write_sr_cr(), which are now called by micron_set_dummy_cycles().
>> -/*
>> * Write status register 1 byte
>> * Returns negative if error occurred.
>> */
>> @@ -1012,6 +994,81 @@ static int set_quad_mode(struct spi_nor *nor, struct
>> flash_info *info) }
>> }
>>
>> +static int micron_set_dummy_cycles(struct spi_nor *nor)
>> +{
>> + int ret;
>> + u8 val, mask;
>> +
>> + /* read the Volatile Configuration Register (VCR) */
>
> NIT: If this is a sentence, start it with capital letter and end it with
> fullstop :)
>
done for the next version
>> + ret = nor->read_reg(nor, SPINOR_OP_RD_VCR, &val, 1);
>> + if (ret < 0) {
>> + dev_err(nor->dev, "error %d reading VCR\n", ret);
>> + return ret;
>> + }
>> +
>> + write_enable(nor);
>> +
>> + /* update the number of dummy into the VCR */
>
> DTTO
>
done for the next version
>> + mask = GENMASK(7, 4);
>> + val &= ~mask;
>> + val |= (nor->read_dummy << 4) & mask;
>> + ret = nor->write_reg(nor, SPINOR_OP_WR_VCR, &val, 1, 0);
>> + if (ret < 0) {
>> + dev_err(nor->dev, "error while writing VCR register\n");
>> + return ret;
>> + }
>> +
>> + ret = spi_nor_wait_till_ready(nor);
>> + if (ret)
>> + return ret;
>> +
>> + return 0;
>> +}
>> +
>> +/*
>> + * Dummy Cycle calculation for different type of read.
>> + * It can be used to support more commands with
>> + * different dummy cycle requirements.
>> + */
>> +static int spi_nor_read_dummy_cycles(struct spi_nor *nor,
>> + const struct flash_info *info)
>> +{
>> + struct device_node *np = nor->dev->of_node;
>> + u32 num_dummy_cycles;
>> +
>> + if (np && !of_property_read_u32(np, "m25p,num-dummy-cycles",
>> + &num_dummy_cycles)) {
>> + nor->read_dummy = num_dummy_cycles;
>> +
>> + /*
>> + * This switch block might be moved after the if...then...else
>> + * statement but it was not tested with all Spansion or Micron
>> + * memories.
>> + * Now the "m25p,num-dummy-cycles" property needs to be
>> + * explicitly set in the device tree so the switch statement is
>> + * executed. This should avoid unwanted side effects and keep
>> + * backward compatibility.
>> + */
>> + switch (JEDEC_MFR(info)) {
>> + case CFI_MFR_ST:
>> + return micron_set_dummy_cycles(nor);
>> + default:
>
> If you do have m25p,num-dummy-cycles set for non-micron flash, you have a
> problem here I believe.
>
>> + break;
>> + }
>> + } else {
>
> The solution would be to drop this else {} bit here, so that if you fail in
> the DT-based configuration, you fall back to this old behavior. What do you
> think please ? :)
>
Good idea!
I also add a trace for the default case of "switch (JEDEC_MFR(info))":
dev_warn(dev, "can't set the number of dummy cycles\n");
So the user is notified that the driver could not use the value of
"m25p,num-dummy-cycles" from the DT before falling back to the legacy
code.
>> + switch (nor->flash_read) {
>> + case SPI_NOR_FAST:
>> + case SPI_NOR_DUAL:
>> + case SPI_NOR_QUAD:
>> + nor->read_dummy = 8;
>> + case SPI_NOR_NORMAL:
>> + nor->read_dummy = 0;
>> + }
>> + }
>> +
>> + return 0;
>> +}
>
> [...]
>
thanks for the review!
Best regards,
Cyrille
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2015-08-24 16:42 UTC|newest]
Thread overview: 70+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-24 10:13 [PATCH linux-next v4 0/5] add driver for Atmel QSPI controller Cyrille Pitchen
2015-08-24 10:13 ` Cyrille Pitchen
2015-08-24 10:13 ` Cyrille Pitchen
2015-08-24 10:13 ` Cyrille Pitchen
2015-08-24 10:13 ` [PATCH linux-next v4 1/5] mtd: spi-nor: notify (Q)SPI controller about protocol change Cyrille Pitchen
2015-08-24 10:13 ` Cyrille Pitchen
2015-08-24 10:13 ` Cyrille Pitchen
2015-08-24 10:16 ` Marek Vasut
2015-08-24 10:16 ` Marek Vasut
2015-08-24 10:13 ` [PATCH linux-next v4 2/5] Documentation: mtd: add a DT property to set the number of dummy cycles Cyrille Pitchen
2015-08-24 10:13 ` Cyrille Pitchen
2015-08-24 10:13 ` Cyrille Pitchen
2015-08-24 10:13 ` Cyrille Pitchen
2015-08-24 10:13 ` [PATCH linux-next v4 3/5] mtd: spi-nor: allow to tune " Cyrille Pitchen
2015-08-24 10:13 ` Cyrille Pitchen
2015-08-24 10:13 ` Cyrille Pitchen
2015-08-24 10:13 ` Cyrille Pitchen
2015-08-24 10:48 ` Marek Vasut
2015-08-24 10:48 ` Marek Vasut
2015-08-24 16:42 ` Cyrille Pitchen [this message]
2015-08-24 16:42 ` Cyrille Pitchen
2015-08-24 16:42 ` Cyrille Pitchen
2015-08-24 16:42 ` Cyrille Pitchen
2015-08-24 16:48 ` Marek Vasut
2015-08-24 16:48 ` Marek Vasut
2015-08-24 16:48 ` Marek Vasut
2015-08-24 10:13 ` [PATCH linux-next v4 4/5] Documentation: atmel-quadspi: add binding file for Atmel QSPI driver Cyrille Pitchen
2015-08-24 10:13 ` Cyrille Pitchen
2015-08-24 10:13 ` Cyrille Pitchen
2015-08-24 10:13 ` Cyrille Pitchen
2015-08-24 10:22 ` Marek Vasut
2015-08-24 10:22 ` Marek Vasut
2015-08-24 10:22 ` Marek Vasut
2015-08-24 10:14 ` [PATCH linux-next v4 5/5] mtd: atmel-quadspi: add driver for Atmel QSPI controller Cyrille Pitchen
2015-08-24 10:14 ` Cyrille Pitchen
2015-08-24 10:14 ` Cyrille Pitchen
2015-08-24 11:03 ` Marek Vasut
2015-08-24 11:03 ` Marek Vasut
2015-08-24 11:03 ` Marek Vasut
2015-08-24 12:49 ` Russell King - ARM Linux
2015-08-24 12:49 ` Russell King - ARM Linux
2015-08-24 12:49 ` Russell King - ARM Linux
2015-08-24 13:15 ` Marek Vasut
2015-08-24 13:15 ` Marek Vasut
2015-08-24 17:04 ` Cyrille Pitchen
2015-08-24 17:04 ` Cyrille Pitchen
2015-08-24 17:04 ` Cyrille Pitchen
2015-08-24 17:45 ` Marek Vasut
2015-08-24 17:45 ` Marek Vasut
2015-08-24 17:45 ` Marek Vasut
2015-08-25 9:46 ` Jonas Gorski
2015-08-25 9:46 ` Jonas Gorski
2015-08-25 9:46 ` Jonas Gorski
2015-08-25 10:21 ` Cyrille Pitchen
2015-08-25 10:21 ` Cyrille Pitchen
2015-08-25 10:21 ` Cyrille Pitchen
2015-08-25 10:17 ` Cyrille Pitchen
2015-08-25 10:17 ` Cyrille Pitchen
2015-08-25 10:17 ` Cyrille Pitchen
2015-08-25 10:22 ` Marek Vasut
2015-08-25 10:22 ` Marek Vasut
2015-08-25 10:22 ` Marek Vasut
2015-08-25 15:57 ` Brian Norris
2015-08-25 15:57 ` Brian Norris
2015-08-25 15:57 ` Brian Norris
2015-08-25 1:44 ` Bean Huo 霍斌斌 (beanhuo)
2015-08-25 1:44 ` Bean Huo 霍斌斌 (beanhuo)
2015-08-25 11:24 ` Cyrille Pitchen
2015-08-25 11:24 ` Cyrille Pitchen
2015-08-25 11:24 ` Cyrille Pitchen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=55DB4986.1000207@atmel.com \
--to=cyrille.pitchen@atmel.com \
--cc=beanhuo@micron.com \
--cc=ben@decadent.org.uk \
--cc=broonie@kernel.org \
--cc=computersforpeace@gmail.com \
--cc=devicetree@vger.kernel.org \
--cc=dwmw2@infradead.org \
--cc=galak@codeaurora.org \
--cc=ijc+devicetree@hellion.org.uk \
--cc=juhosg@openwrt.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=linux-spi@vger.kernel.org \
--cc=marex@denx.de \
--cc=mark.rutland@arm.com \
--cc=nicolas.ferre@atmel.com \
--cc=pawel.moll@arm.com \
--cc=robh+dt@kernel.org \
--cc=shijie.huang@intel.com \
--cc=zajec5@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.