Skip to content

Commit 15e27d1

Browse files
passgatmiquelraynal
authored andcommitted
mtd: rawnand: gpmi: validate controller clock rate
What to do when the real rate of the gpmi clock is not equal to the required one? The solutions proposed in [1] did not lead to a conclusion on how to validate the clock rate, so, inspired by the document [2], I consider the rate correct only if not lower or equal to the rate of the previous edo mode. In fact, in chapter 4.16.2 (NV-DDR) of the document [2], it is written that "If the host selects timing mode n, then its clock period shall be faster than the clock period of timing mode n-1 and slower than or equal to the clock period of timing mode n.". I thought that it could therefore also be used in this case, without therefore having to define the valid rate ranges empirically. For example, suppose that gpmi_nfc_compute_timings() is called to set edo mode 5 (100MHz) but the rate returned by clk_round_rate() is 80MHz (edo mode 4). In this case gpmi_nfc_compute_timings() will return error, and will be called again to set edo mode 4, which this time will be successful. [1] https://lore.kernel.org/r/[email protected] [2] http://www.onfi.org/-/media/client/onfi/specs/onfi_3_0_gold.pdf?la=en Co-developed-by: Michael Trimarchi <[email protected]> Signed-off-by: Michael Trimarchi <[email protected]> Signed-off-by: Dario Binacchi <[email protected]> Tested-by: Sascha Hauer <[email protected]> Reviewed-by: Sascha Hauer <[email protected]> Signed-off-by: Miquel Raynal <[email protected]> Link: https://lore.kernel.org/linux-mtd/[email protected]
1 parent 2970bf5 commit 15e27d1

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -644,8 +644,8 @@ static int bch_set_geometry(struct gpmi_nand_data *this)
644644
* RDN_DELAY = ----------------------- {3}
645645
* RP
646646
*/
647-
static void gpmi_nfc_compute_timings(struct gpmi_nand_data *this,
648-
const struct nand_sdr_timings *sdr)
647+
static int gpmi_nfc_compute_timings(struct gpmi_nand_data *this,
648+
const struct nand_sdr_timings *sdr)
649649
{
650650
struct gpmi_nfc_hardware_timing *hw = &this->hw;
651651
struct resources *r = &this->resources;
@@ -657,23 +657,33 @@ static void gpmi_nfc_compute_timings(struct gpmi_nand_data *this,
657657
int sample_delay_ps, sample_delay_factor;
658658
u16 busy_timeout_cycles;
659659
u8 wrn_dly_sel;
660+
unsigned long clk_rate, min_rate;
660661

661662
if (sdr->tRC_min >= 30000) {
662663
/* ONFI non-EDO modes [0-3] */
663664
hw->clk_rate = 22000000;
665+
min_rate = 0;
664666
wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS;
665667
} else if (sdr->tRC_min >= 25000) {
666668
/* ONFI EDO mode 4 */
667669
hw->clk_rate = 80000000;
670+
min_rate = 22000000;
668671
wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY;
669672
} else {
670673
/* ONFI EDO mode 5 */
671674
hw->clk_rate = 100000000;
675+
min_rate = 80000000;
672676
wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY;
673677
}
674678

675-
hw->clk_rate = clk_round_rate(r->clock[0], hw->clk_rate);
679+
clk_rate = clk_round_rate(r->clock[0], hw->clk_rate);
680+
if (clk_rate <= min_rate) {
681+
dev_err(this->dev, "clock setting: expected %ld, got %ld\n",
682+
hw->clk_rate, clk_rate);
683+
return -ENOTSUPP;
684+
}
676685

686+
hw->clk_rate = clk_rate;
677687
/* SDR core timings are given in picoseconds */
678688
period_ps = div_u64((u64)NSEC_PER_SEC * 1000, hw->clk_rate);
679689

@@ -714,6 +724,7 @@ static void gpmi_nfc_compute_timings(struct gpmi_nand_data *this,
714724
hw->ctrl1n |= BF_GPMI_CTRL1_RDN_DELAY(sample_delay_factor) |
715725
BM_GPMI_CTRL1_DLL_ENABLE |
716726
(use_half_period ? BM_GPMI_CTRL1_HALF_PERIOD : 0);
727+
return 0;
717728
}
718729

719730
static int gpmi_nfc_apply_timings(struct gpmi_nand_data *this)
@@ -769,6 +780,7 @@ static int gpmi_setup_interface(struct nand_chip *chip, int chipnr,
769780
{
770781
struct gpmi_nand_data *this = nand_get_controller_data(chip);
771782
const struct nand_sdr_timings *sdr;
783+
int ret;
772784

773785
/* Retrieve required NAND timings */
774786
sdr = nand_get_sdr_timings(conf);
@@ -784,7 +796,9 @@ static int gpmi_setup_interface(struct nand_chip *chip, int chipnr,
784796
return 0;
785797

786798
/* Do the actual derivation of the controller timings */
787-
gpmi_nfc_compute_timings(this, sdr);
799+
ret = gpmi_nfc_compute_timings(this, sdr);
800+
if (ret)
801+
return ret;
788802

789803
this->hw.must_apply_timings = true;
790804

0 commit comments

Comments
 (0)