mtd: rawnand: Add timings for Kioxia TH58NVG2S3HBAI4
Hi Miquel,
Quoted 4 lines
I just a branch with a new helper to fill this field, it is called
onfi_find_equivalent_sdr_mode().It is only compile tested so please verify it works.
I have created a new patchset that I will send shortly. This patchset does however not use onfi_find_equivalent_sdr_mode(..), that could be a future improvment. My patchset falls back to mode 0 if the specialized timings does not work for the controller.
Quoted 6 lines
Quoted 2 lines
+static int th58nvg2s3hbai4_init_data_interface(struct
nand_chipI renamed the hook so the helper should be
th58..._choose_data_interface()
Quoted 8 lines
Quoted 2 lines
*chip) +{
+chip->data_interface=th58nvg2s3hbai4_timings;this data interface should be tested against the controller's capabilities and return an error otherwise.
Please check that, in case of error (simulate it) it fallbacks to mode 0 and does not fail silently.
I have tested this on my new patchset and it works.
Best regards,
Rickard
________________________________________
Från: Miquel Raynal <[email protected]>
Skickat: den 19 maj 2020 14:08
Till: Rickard X Andersson
Kopia: [email protected]
Ämne: Re: [PATCH 2/2] mtd: rawnand: Add timings for Kioxia TH58NVG2S3HBAI4
Hi Rickard,
Rickard Andersson <[email protected]> wrote on Thu, 14 May 2020 11:13:42 +0200:
Quoted 38 lines
From: Rickard x Andersson <[email protected]>
The Kioxia/Toshiba TH58NVG2S3HBAI4 NAND memory is not a ONFI compliant memory. The timings of the memory is quite close to ONFI mode 4 but is breaking that spec.
Erase block read speed is increased from 6910 KiB/s to 13490 KiB/s. Erase block write speed is increased from 3350 KiB/s to 4410 KiB/s.
Tested on IMX6SX which has a NAND controller supporting EDO mode.
Signed-off-by Rickard x Andersson <[email protected]>--- drivers/mtd/nand/raw/nand_ids.c | 3 ++ drivers/mtd/nand/raw/nand_toshiba.c | 61 +++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+)drivers/mtd/nand/raw/nand_ids.c +3
-0@@ -52,6 +52,9 @@ struct nand_flash_dev nand_flash_ids[] = { { .id = {0xad, 0xde, 0x94, 0xda, 0x74, 0xc4} },SZ_8K ,SZ_8K ,SZ_2M ,NAND_NEED_SCRAMBLING ,6 ,640 , NAND_ECC_INFO(40, SZ_1K), 4 }, + {"TH58NVG2S3HBAI4 4G 3.3V 8-bit", + { .id = {0x98, 0xdc, 0x91, 0x15, 0x76} }, + SZ_2K, SZ_512, SZ_128K, 0, 5, 128, NAND_ECC_INFO(8, SZ_512) },LEGACY_ID_NAND ("NAND 4MiB 5V 8-bit" ,0x6B ,4 ,SZ_8K ,SP_OPTIONS ), LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xE3, 4, SZ_8K, SP_OPTIONS),drivers/mtd/nand/raw/nand_toshiba.c +0
-0
drivers/mtd/nand/raw/nand_toshiba.c line 31
Quoted 6 lines
drivers/mtd/nand/raw/nand_toshiba.c +3
-0@@ -26,6 +26,52 @@/* Max ECC Steps for BENAND */ #define TOSHIBA_NAND_MAX_ECC_STEPS 8 +static const struct nand_data_interface th58nvg2s3hbai4_timings = { + .type =NAND_SDR_IFACE , + .timings.mode =0 ,
I just a branch with a new helper to fill this field, it is called onfi_find_equivalent_sdr_mode().
It is only compile tested so please verify it works.
Quoted 47 lines
drivers/mtd/nand/raw/nand_toshiba.c +43
-0+ .timings.sdr = { + .tPROG_max = 700000000, + .tBERS_max = 5000000000, + .tCCS_min = 500000, + .tR_max = 200000000, + .tADL_min = 400000, + .tALH_min = 5000, + .tALS_min = 12000, + .tAR_min = 10000, + .tCEA_max = 25000, + .tCEH_min = 20000, + .tCH_min = 5000, + .tCHZ_max = 20000, + .tCLH_min = 5000, + .tCLR_min = 10000, + .tCLS_min = 12000, + .tCOH_min = 0, + .tCS_min = 20000, + .tDH_min = 5000, + .tDS_min = 12000, + .tFEAT_max = 1000000, + .tIR_min = 0, + .tITC_max = 1000000, + .tRC_min = 25000, + .tREA_max = 20000, + .tREH_min = 10000, + .tRHOH_min = 25000, + .tRHW_min = 30000, + .tRHZ_max = 60000, + .tRLOH_min = 5000, + .tRP_min = 12000, + .tRR_min = 20000, + .tRST_max = 500000000, + .tWB_max = 100000, + .tWC_min = 25000, + .tWH_min = 10000, + .tWHR_min = 60000, + .tWP_min = 12000, + .tWW_min = 100000, + } +}; + +static int toshiba_nand_benand_read_eccstatus_op (struct nand_chip *chip,u8 *buf) {
drivers/mtd/nand/raw/nand_toshiba.c static void toshiba_nand_decode_id(struct · line 243
Quoted 4 lines
drivers/mtd/nand/raw/nand_toshiba.c +1
-0@@ -194,6 +240,13 @@ static void toshiba_nand_decode_id(struct nand_chip *chip) } } +static int th58nvg2s3hbai4_init_data_interface(struct nand_chip
I renamed the hook so the helper should be
th58..._choose_data_interface()
drivers/mtd/nand/raw/nand_toshiba.c static void toshiba_nand_decode_id(struct · line 245
Quoted 2 lines
drivers/mtd/nand/raw/nand_toshiba.c +1
-0*chip) +{ + chip->data_interface = th58nvg2s3hbai4_timings;
this data interface should be tested against the controller's capabilities and return an error otherwise.
Please check that, in case of error (simulate it) it fallbacks to mode 0 and does not fail silently.
Quoted 22 lines
drivers/mtd/nand/raw/nand_toshiba.c +10
-0+ +return 0 ; +} +static int tc58teg5dclta00_init (struct nand_chip *chip) {struct mtd_info *mtd =nand_to_mtd (chip);@@ -205,6 +258,12 @@ static int tc58teg5dclta00_init(struct nand_chip *chip) return 0; } +static int th58nvg2s3hbai4_init (struct nand_chip *chip) +{ + chip->ops.init_data_interface = th58nvg2s3hbai4_init_data_interface; +return 0 ; +} +static int toshiba_nand_init (struct nand_chip *chip) {if (nand_is_slc(chip))
drivers/mtd/nand/raw/nand_toshiba.c static int toshiba_nand_init(struct nand_chip · line 283
Quoted 8 lines
drivers/mtd/nand/raw/nand_toshiba.c +2
-0@@ -217,6 +276,8 @@ static int toshiba_nand_init(struct nand_chip *chip)if (!strcmp ("TC58TEG5DCLTA00" , chip->parameters.model))tc58teg5dclta00_init (chip); +if (!strncmp ("TH58NVG2S3HBAI4" , chip->parameters.model,15 )) +th58nvg2s3hbai4_init (chip);return 0 ; }
Thanks,
Miquèl
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
Miquel Raynal
maintainerHi Rickard,
Rickard X Andersson <[email protected]> wrote on Wed, 20 May 2020 13:32:14 +0000:
Quoted 8 lines
Hi Miquel,
Quoted 4 lines
I just a branch with a new helper to fill this field, it is called
onfi_find_equivalent_sdr_mode().It is only compile tested so please verify it works.
I have created a new patchset that I will send shortly. This patchset does however not use
onfi_find_equivalent_sdr_mode(..), that could be a future improvment. My patchset falls back to mode 0 if the specialized timings does not work for the controller.
Thanks for updating!
Actually I wrote it because of a previous discussion with Boris who told me that this mode field would be badly understood and he actually got it right as in your previous submission this field was set to 0 while, IIRC, you told me it was close to mode 3. This is important to controllers that cannot tweak the parameters but just pick an ONFI mode. So the timings they choose must fit the slowest mins and fastest maxs of your new set of timings. Hence the use of the helper which seems needed. It is actually pretty straightforward so I don't understand your choice of not making use of it?
As this is the primary contribution of this type, I would like to get it right so that other contributors can refer to it :)
Thanks,
Miquèl
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
Quoted 14 lines
Quoted 1 line
I have created a new patchset that I will send shortly. This patchset does however not use
onfi_find_equivalent_sdr_mode(..), that could be a future improvment. My patchset falls back to mode 0 if the specialized timings does not work for the controller.Thanks for updating!
Actually I wrote it because of a previous discussion with Boris who told me that this mode field would be badly understood and he actually got it right as in your previous submission this field was set to 0 while, IIRC, you told me it was close to mode 3. This is important to controllers that cannot tweak the parameters but just pick an ONFI mode. So the timings they choose must fit the slowest mins and fastest maxs of your new set of timings. Hence the use of the helper which seems needed. It is actually pretty straightforward so I don't understand your choice of not making use of it?
Quoted 2 lines
As this is the primary contribution of this type, I would like to get it right so that other contributors can refer to it :)
If I understand you correctly you want me to use onfi_find_equivalent_sdr_mode in order to find the corresponding onfi mode. Then you want me to use onfi_fill_data_interface and loop towards mode 0 checking which mode the controller accepts? I just thought it was a "messy" to duplicate this code in all vendor drivers. Or do you mean that I should just use onfi_find_equivalent_sdr_mode to set ."timings.mode" and let nand_base to do the looping in case error is returned from th58nvg2s3hbai4_choose_data_interface (i.e specialized timings not accepted by the controller).
Thanks,
Rickard
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
Miquel Raynal
maintainerHi Rickard,
Rickard X Andersson <[email protected]> wrote on Wed, 20 May 2020 14:16:57 +0000:
Quoted 14 lines
Quoted 14 lines
Quoted 1 line
I have created a new patchset that I will send shortly. This patchset does however not use
onfi_find_equivalent_sdr_mode(..), that could be a future improvment. My patchset falls back to mode 0 if the specialized timings does not work for the controller.Thanks for updating!
Actually I wrote it because of a previous discussion with Boris who told me that this mode field would be badly understood and he actually got it right as in your previous submission this field was set to 0 while, IIRC, you told me it was close to mode 3. This is important to controllers that cannot tweak the parameters but just pick an ONFI mode. So the timings they choose must fit the slowest mins and fastest maxs of your new set of timings. Hence the use of the helper which seems needed. It is actually pretty straightforward so I don't understand your choice of not making use of it?
Quoted 5 lines
Quoted 2 lines
As this is the primary contribution of this type, I would like to get it right so that other contributors can refer to it :)
If I understand you correctly you want me to use
onfi_find_equivalent_sdr_modein order to find the corresponding onfi mode. Then you want me to useonfi_fill_data_interfaceand loop towards mode 0 checking which mode the controller accepts? I just thought it was a "messy" to duplicate this code in all vendor drivers. Or do you mean that I should just useonfi_find_equivalent_sdr_modeto set ."timings.mode" and letnand_baseto do the looping in case error is returned fromth58nvg2s3hbai4_choose_data_interface(i.e specialized timings not accepted by the controller).
Sorry for the misunderstanding. What I think you should try is:
1/ call onfi_find_equivalent_sdr_mode() to set the timings.mode field. 2/ call nand_controller_supports_data_interface()
3/ if the controller supports the timings, set chip->default_timing_mode accordingly and return 0.
4/ if the controller does not support the timings, you may want to propose other standard timings to test by setting chip->default_timing_mode anyway but returning an error which means "best interface has not been found yet" so the rest of the choose_data_interface() helper will try the remaining ONFI modes automatically (fallbacks to 0 anyway).
Thanks,
Miquèl
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
Quoted 14 lines
Quoted 2 lines
If I understand you correctly you want me to use
onfi_find_equivalent_sdr_modein order to find the corresponding onfi mode. Then you want me to useonfi_fill_data_interfaceand loop towards mode 0 checking which mode the controller accepts? I just thought it was a "messy" to duplicate this code in all vendor drivers. Or do you mean that I should just useonfi_find_equivalent_sdr_modeto set ."timings.mode" and letnand_baseto do the looping in case error is returned fromth58nvg2s3hbai4_choose_data_interface(i.e specialized timings not accepted by the controller).Sorry for the misunderstanding. What I think you should try is:
1/ callonfi_find_equivalent_sdr_mode()to set the timings.mode field. 2/ callnand_controller_supports_data_interface()
3/ if the controller supports the timings, setchip->default_timing_modeaccordingly and return 0.
4/ if the controller does not support the timings, you may want to propose other standard timings to test by settingchip->default_timing_modeanyway but returning an error which means "best interface has not been found yet" so the rest of thechoose_data_interface()helper will try the remaining ONFI modes automatically (fallbacks to 0 anyway).
Thanks! Now I understand, will fix this on monday.
BR
Rickard
________________________________________
Från: Miquel Raynal <[email protected]>
Skickat: den 20 maj 2020 16:29
Till: Rickard X Andersson
Kopia: [email protected]; Boris Brezillon
Ämne: Re: [PATCH 2/2] mtd: rawnand: Add timings for Kioxia TH58NVG2S3HBAI4
Hi Rickard,
Rickard X Andersson <[email protected]> wrote on Wed, 20 May 2020 14:16:57 +0000:
Quoted 14 lines
Quoted 14 lines
Quoted 1 line
I have created a new patchset that I will send shortly. This patchset does however not use
onfi_find_equivalent_sdr_mode(..), that could be a future improvment. My patchset falls back to mode 0 if the specialized timings does not work for the controller.Thanks for updating!
Actually I wrote it because of a previous discussion with Boris who told me that this mode field would be badly understood and he actually got it right as in your previous submission this field was set to 0 while, IIRC, you told me it was close to mode 3. This is important to controllers that cannot tweak the parameters but just pick an ONFI mode. So the timings they choose must fit the slowest mins and fastest maxs of your new set of timings. Hence the use of the helper which seems needed. It is actually pretty straightforward so I don't understand your choice of not making use of it?
Quoted 5 lines
Quoted 2 lines
As this is the primary contribution of this type, I would like to get it right so that other contributors can refer to it :)
If I understand you correctly you want me to use
onfi_find_equivalent_sdr_modein order to find the corresponding onfi mode. Then you want me to useonfi_fill_data_interfaceand loop towards mode 0 checking which mode the controller accepts? I just thought it was a "messy" to duplicate this code in all vendor drivers. Or do you mean that I should just useonfi_find_equivalent_sdr_modeto set ."timings.mode" and letnand_baseto do the looping in case error is returned fromth58nvg2s3hbai4_choose_data_interface(i.e specialized timings not accepted by the controller).
Sorry for the misunderstanding. What I think you should try is:
1/ call onfi_find_equivalent_sdr_mode() to set the timings.mode field. 2/ call nand_controller_supports_data_interface()
3/ if the controller supports the timings, set chip->default_timing_mode accordingly and return 0.
4/ if the controller does not support the timings, you may want to propose other standard timings to test by setting chip->default_timing_mode anyway but returning an error which means "best interface has not been found yet" so the rest of the choose_data_interface() helper will try the remaining ONFI modes automatically (fallbacks to 0 anyway).
Thanks,
Miquèl
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
Quoted 8 lines · On Wed, 20 May 2020 14:42:31 +0000 Rickard X Andersson…
Quoted 8 lines
Quoted 2 lines
If I understand you correctly you want me to use
onfi_find_equivalent_sdr_modein order to find the corresponding onfi mode. Then you want me to useonfi_fill_data_interfaceand loop towards mode 0 checking which mode the controller accepts? I just thought it was a "messy" to duplicate this code in all vendor drivers. Or do you mean that I should just useonfi_find_equivalent_sdr_modeto set ."timings.mode" and letnand_baseto do the looping in case error is returned fromth58nvg2s3hbai4_choose_data_interface(i.e specialized timings not accepted by the controller).Sorry for the misunderstanding. What I think you should try is:
1/ callonfi_find_equivalent_sdr_mode()to set the timings.mode field. 2/ callnand_controller_supports_data_interface()
3/ if the controller supports the timings, setchip->default_timing_modeaccordingly and return 0.
Why do we have to set the default_timing_mode field? Can't we just set timings.mode directly?
Quoted 6 lines
Quoted 6 lines
4/ if the controller does not support the timings, you may want to propose other standard timings to test by setting
chip->default_timing_modeanyway but returning an error which means "best interface has not been found yet" so the rest of thechoose_data_interface()helper will try the remaining ONFI modes automatically (fallbacks to 0 anyway).
Again, I don't see why setting chip->default_timing_mode is needed here, and I'm not sure trying remaining ONFI modes is useful, I guess we can just fall back on mode 0 in that case.
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
Miquel Raynal
maintainerHi Boris,
Boris Brezillon <[email protected]> wrote on Wed, 20 May 2020 16:50:22 +0200:
Quoted 22 lines
Quoted 8 lines · On Wed, 20 May 2020 14:42:31 +0000 Rickard X Andersson…
Quoted 8 lines
Quoted 2 lines
If I understand you correctly you want me to use
onfi_find_equivalent_sdr_modein order to find the corresponding onfi mode. Then you want me to useonfi_fill_data_interfaceand loop towards mode 0 checking which mode the controller accepts? I just thought it was a "messy" to duplicate this code in all vendor drivers. Or do you mean that I should just useonfi_find_equivalent_sdr_modeto set ."timings.mode" and letnand_baseto do the looping in case error is returned fromth58nvg2s3hbai4_choose_data_interface(i.e specialized timings not accepted by the controller).Sorry for the misunderstanding. What I think you should try is:
1/ callonfi_find_equivalent_sdr_mode()to set the timings.mode field. 2/ callnand_controller_supports_data_interface()
3/ if the controller supports the timings, setchip->default_timing_modeaccordingly and return 0.Why do we have to set the
default_timing_modefield? Can't we just set timings.mode directly?Quoted 6 lines
Quoted 6 lines
4/ if the controller does not support the timings, you may want to propose other standard timings to test by setting
chip->default_timing_modeanyway but returning an error which means "best interface has not been found yet" so the rest of thechoose_data_interface()helper will try the remaining ONFI modes automatically (fallbacks to 0 anyway).
Quoted 3 lines
Again, I don't see why setting
chip->default_timing_modeis needed here, and I'm not sure trying remaining ONFI modes is useful, I guess we can just fall back on mode 0 in that case.
It is needed because of the logic in nand_reset() which does not apply the data interface after a reset if this field is null.
Otherwise I also wondered if falling back to regular ONFI mode was useful. If this is not, we can just return after the call to chip->ops.choose_data_interface().
Thanks,
Miquèl
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
Quoted 27 lines · On Wed, 20 May 2020 17:12:46 +0200 Miquel Raynal <[email protected]>…
Hi Boris,
Boris Brezillon <[email protected]> wrote on Wed, 20 May 2020 16:50:22 +0200:
Quoted 22 lines
Quoted 8 lines · On Wed, 20 May 2020 14:42:31 +0000 Rickard X Andersson…
Quoted 8 lines
Quoted 2 lines
If I understand you correctly you want me to use
onfi_find_equivalent_sdr_modein order to find the corresponding onfi mode. Then you want me to useonfi_fill_data_interfaceand loop towards mode 0 checking which mode the controller accepts? I just thought it was a "messy" to duplicate this code in all vendor drivers. Or do you mean that I should just useonfi_find_equivalent_sdr_modeto set ."timings.mode" and letnand_baseto do the looping in case error is returned fromth58nvg2s3hbai4_choose_data_interface(i.e specialized timings not accepted by the controller).Sorry for the misunderstanding. What I think you should try is:
1/ callonfi_find_equivalent_sdr_mode()to set the timings.mode field. 2/ callnand_controller_supports_data_interface()
3/ if the controller supports the timings, setchip->default_timing_modeaccordingly and return 0.Why do we have to set the
default_timing_modefield? Can't we just set timings.mode directly?Quoted 6 lines
Quoted 6 lines
4/ if the controller does not support the timings, you may want to propose other standard timings to test by setting
chip->default_timing_modeanyway but returning an error which means "best interface has not been found yet" so the rest of thechoose_data_interface()helper will try the remaining ONFI modes automatically (fallbacks to 0 anyway).
Quoted 6 lines
Quoted 3 lines
Again, I don't see why setting
chip->default_timing_modeis needed here, and I'm not sure trying remaining ONFI modes is useful, I guess we can just fall back on mode 0 in that case.It is needed because of the logic in
nand_reset()which does not apply the data interface after a reset if this field is null.
We should probably replace that check by a memcmp():
if (!memcmp(&chip->data_interface, saved_data_intf, sizeof(saved_data_intf))) return 0;
And maybe we should allocate this struct instead of copying things around (have a "default/reset timings" object that's shared by all drivers and matches timing mode 0, and a "best timing" object that's allocated at init time).
Quoted 4 lines
Otherwise I also wondered if falling back to regular ONFI mode was useful. If this is not, we can just return after the call to
chip->ops.choose_data_interface().
Or maybe we could expose this logic as a helper:
static int
nand_choose_best_sdr_timings(struct nand_chip *,
struct nand_sdr_timings *best_timings)
{
/*
* 1/ pick the closest mode and assign best_timings->mode
* using onfi_find_equivalent_sdr_mode()
* 2/ call controller->setup_data_interface(check_only, best_timings);
* 3/ pick timings of best_timings->mode - 1 if it fails and go back to
* #2, return 0 otherwise.
*/
}
This way the driver doesn't have to duplicate the logic, it only has to fill the best_timings struct accordingly, and the core can simply do:
if (chip->ops.choose_data_interface) return chip->ops.choose_data_interface();
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
Miquel Raynal
maintainerHi Boris,
Boris Brezillon <[email protected]> wrote on Wed, 20 May 2020 17:26:52 +0200:
Quoted 39 lines
Quoted 27 lines · On Wed, 20 May 2020 17:12:46 +0200 Miquel Raynal <[email protected]>…
Hi Boris,
Boris Brezillon <[email protected]> wrote on Wed, 20 May 2020 16:50:22 +0200:
Quoted 22 lines
Quoted 8 lines · On Wed, 20 May 2020 14:42:31 +0000 Rickard X Andersson…
Quoted 8 lines
Quoted 2 lines
If I understand you correctly you want me to use
onfi_find_equivalent_sdr_modein order to find the corresponding onfi mode. Then you want me to useonfi_fill_data_interfaceand loop towards mode 0 checking which mode the controller accepts? I just thought it was a "messy" to duplicate this code in all vendor drivers. Or do you mean that I should just useonfi_find_equivalent_sdr_modeto set ."timings.mode" and letnand_baseto do the looping in case error is returned fromth58nvg2s3hbai4_choose_data_interface(i.e specialized timings not accepted by the controller).Sorry for the misunderstanding. What I think you should try is:
1/ callonfi_find_equivalent_sdr_mode()to set the timings.mode field. 2/ callnand_controller_supports_data_interface()
3/ if the controller supports the timings, setchip->default_timing_modeaccordingly and return 0.Why do we have to set the
default_timing_modefield? Can't we just set timings.mode directly?Quoted 6 lines
Quoted 6 lines
4/ if the controller does not support the timings, you may want to propose other standard timings to test by setting
chip->default_timing_modeanyway but returning an error which means "best interface has not been found yet" so the rest of thechoose_data_interface()helper will try the remaining ONFI modes automatically (fallbacks to 0 anyway).Quoted 6 lines
Quoted 3 lines
Again, I don't see why setting
chip->default_timing_modeis needed here, and I'm not sure trying remaining ONFI modes is useful, I guess we can just fall back on mode 0 in that case.It is needed because of the logic in
nand_reset()which does not apply the data interface after a reset if this field is null.We should probably replace that check by a
memcmp():
Quoted 8 lines
if (!memcmp(&chip->data_interface, saved_data_intf, sizeof(saved_data_intf))) return 0;And maybe we should allocate this struct instead of copying things around (have a "default/reset timings" object that's shared by all drivers and matches timing mode 0, and a "best timing" object that's allocated at init time).
Indeed, checking if a pointer has been set is much less expensive than a memcmp I suppose. I'll try to come up with something.
Quoted 21 lines
Quoted 5 lines
Otherwise I also wondered if falling back to regular ONFI mode was useful. If this is not, we can just return after the call to
chip->ops.choose_data_interface().Or maybe we could expose this logic as a helper:
static int
nand_choose_best_sdr_timings(structnand_chip*,
structnand_sdr_timings*best_timings)
{
/*
* 1/ pick the closest mode and assignbest_timings->mode
* usingonfi_find_equivalent_sdr_mode()
* 2/ callcontroller->setup_data_interface(check_only, best_timings);
* 3/ pick timings ofbest_timings->mode- 1 if it fails and go back to
* #2, return 0 otherwise.
*/
}
Quoted 6 lines
This way the driver doesn't have to duplicate the logic, it only has to fill the
best_timingsstruct accordingly, and the core can simply do:if (chip->ops.choose_data_interface) return chip->ops.choose_data_interface();
Well, that's very close to what I just proposed, no? The difference being that I was reusing the existing code (and already adapted it to DDR modes BTW) because "picking timings of best_timings->mode - 1 if it fails and go back to #2" is precisely what nand_choose_data_interface() does.
Let me propose something with the above changes.
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
Quoted 77 lines · On Wed, 20 May 2020 22:43:54 +0200 Miquel Raynal <[email protected]>…
Hi Boris,
Boris Brezillon <[email protected]> wrote on Wed, 20 May 2020 17:26:52 +0200:
Quoted 39 lines
Quoted 27 lines · On Wed, 20 May 2020 17:12:46 +0200 Miquel Raynal <[email protected]>…
Hi Boris,
Boris Brezillon <[email protected]> wrote on Wed, 20 May 2020 16:50:22 +0200:
Quoted 22 lines
Quoted 8 lines · On Wed, 20 May 2020 14:42:31 +0000 Rickard X Andersson…
Quoted 8 lines
Quoted 2 lines
If I understand you correctly you want me to use
onfi_find_equivalent_sdr_modein order to find the corresponding onfi mode. Then you want me to useonfi_fill_data_interfaceand loop towards mode 0 checking which mode the controller accepts? I just thought it was a "messy" to duplicate this code in all vendor drivers. Or do you mean that I should just useonfi_find_equivalent_sdr_modeto set ."timings.mode" and letnand_baseto do the looping in case error is returned fromth58nvg2s3hbai4_choose_data_interface(i.e specialized timings not accepted by the controller).Sorry for the misunderstanding. What I think you should try is:
1/ callonfi_find_equivalent_sdr_mode()to set the timings.mode field. 2/ callnand_controller_supports_data_interface()
3/ if the controller supports the timings, setchip->default_timing_modeaccordingly and return 0.Why do we have to set the
default_timing_modefield? Can't we just set timings.mode directly?Quoted 6 lines
Quoted 6 lines
4/ if the controller does not support the timings, you may want to propose other standard timings to test by setting
chip->default_timing_modeanyway but returning an error which means "best interface has not been found yet" so the rest of thechoose_data_interface()helper will try the remaining ONFI modes automatically (fallbacks to 0 anyway).Quoted 6 lines
Quoted 3 lines
Again, I don't see why setting
chip->default_timing_modeis needed here, and I'm not sure trying remaining ONFI modes is useful, I guess we can just fall back on mode 0 in that case.It is needed because of the logic in
nand_reset()which does not apply the data interface after a reset if this field is null.We should probably replace that check by a
memcmp():Quoted 8 lines
if (!memcmp(&chip->data_interface, saved_data_intf, sizeof(saved_data_intf))) return 0;And maybe we should allocate this struct instead of copying things around (have a "default/reset timings" object that's shared by all drivers and matches timing mode 0, and a "best timing" object that's allocated at init time).
Indeed, checking if a pointer has been set is much less expensive than a memcmp I suppose. I'll try to come up with something.
Quoted 21 lines
Quoted 5 lines
Otherwise I also wondered if falling back to regular ONFI mode was useful. If this is not, we can just return after the call to
chip->ops.choose_data_interface().Or maybe we could expose this logic as a helper:
static int
nand_choose_best_sdr_timings(structnand_chip*,
structnand_sdr_timings*best_timings)
{
/*
* 1/ pick the closest mode and assignbest_timings->mode
* usingonfi_find_equivalent_sdr_mode()
* 2/ callcontroller->setup_data_interface(check_only, best_timings);
* 3/ pick timings ofbest_timings->mode- 1 if it fails and go back to
* #2, return 0 otherwise.
*/
}
Quoted 8 lines
Quoted 6 lines
This way the driver doesn't have to duplicate the logic, it only has to fill the
best_timingsstruct accordingly, and the core can simply do:if (chip->ops.choose_data_interface) return chip->ops.choose_data_interface();Well, that's very close to what I just proposed, no?
Yes, the difference being that you now have the 2 paths clearly separated, and drivers can easily deviate if they need to. It's just a helper (that can be re-used in the fallback path BTW), so it's pretty easy to not call it, or call it as part of something more complex.
Quoted 5 lines
The
difference being that I was reusing the existing code (and already adapted it to DDR modes BTW) because "picking timings ofbest_timings->mode- 1 if it fails and go back to #2" is precisely whatnand_choose_data_interface()does.
Yes, I know, and I'm just suggesting to make that a public helper so vendor drivers can re-use it, if they want.
Quoted 3 lines
Let me propose something with the above changes.
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/