aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHuang Shijie <b32955@freescale.com>2012-09-13 02:57:59 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-09-29 10:56:36 -0400
commit995fbbf563fcec058a1135bdd112ac969c817e65 (patch)
tree5c384059d0ab90fe4c001296f32ddff94ef0e6ca
parente1ca95e3a93c9a0392163a7a6791deda48b5eeca (diff)
mtd: gpmi: add EDO feature for imx6q
When the frequency on the nand chip pins is above 33MHz, the nand EDO(extended Data Out) timing could be applied. The GPMI implements a Feedback read strobe to sample the read data in the EDO timing mode. This patch adds the EDO feature for the gpmi-nand driver. For some onfi nand chips, the mode 4 is the fastest; while for other onfi nand chips, the mode 5 is the fastest. This patch only adds the support for the fastest asynchronous timing mode. So this patch only supports the mode 4 and mode 5. I tested several Micron's ONFI nand chips with EDO enabled, take Micron MT29F32G08MAA for example (in mode 5, 100MHz): 1) The test result BEFORE we add the EDO feature: ================================================= mtd_speedtest: MTD device: 2 mtd_speedtest: MTD device size 209715200, eraseblock size 524288, page size 4096, count of eraseblocks 400, pages per eraseblock 128, OOB size 218 ....................................... mtd_speedtest: testing eraseblock read speed mtd_speedtest: eraseblock read speed is 3632 KiB/s ....................................... mtd_speedtest: testing page read speed mtd_speedtest: page read speed is 3554 KiB/s ....................................... mtd_speedtest: testing 2 page read speed mtd_speedtest: 2 page read speed is 3592 KiB/s ....................................... ================================================= 2) The test result AFTER we add the EDO feature: ================================================= mtd_speedtest: MTD device: 2 mtd_speedtest: MTD device size 209715200, eraseblock size 524288, page size 4096, count of eraseblocks 400, pages per eraseblock 128, OOB size 218 ....................................... mtd_speedtest: testing eraseblock read speed mtd_speedtest: eraseblock read speed is 19555 KiB/s ....................................... mtd_speedtest: testing page read speed mtd_speedtest: page read speed is 17319 KiB/s ....................................... mtd_speedtest: testing 2 page read speed mtd_speedtest: 2 page read speed is 18339 KiB/s ....................................... ================================================= 3) The read data performance is much improved by more then 5 times. Signed-off-by: Huang Shijie <b32955@freescale.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-lib.c214
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.c8
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.h6
3 files changed, 227 insertions, 1 deletions
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
index 010665ca631a..c036e51f3200 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
@@ -737,6 +737,215 @@ return_results:
737 return 0; 737 return 0;
738} 738}
739 739
740/*
741 * <1> Firstly, we should know what's the GPMI-clock means.
742 * The GPMI-clock is the internal clock in the gpmi nand controller.
743 * If you set 100MHz to gpmi nand controller, the GPMI-clock's period
744 * is 10ns. Mark the GPMI-clock's period as GPMI-clock-period.
745 *
746 * <2> Secondly, we should know what's the frequency on the nand chip pins.
747 * The frequency on the nand chip pins is derived from the GPMI-clock.
748 * We can get it from the following equation:
749 *
750 * F = G / (DS + DH)
751 *
752 * F : the frequency on the nand chip pins.
753 * G : the GPMI clock, such as 100MHz.
754 * DS : GPMI_HW_GPMI_TIMING0:DATA_SETUP
755 * DH : GPMI_HW_GPMI_TIMING0:DATA_HOLD
756 *
757 * <3> Thirdly, when the frequency on the nand chip pins is above 33MHz,
758 * the nand EDO(extended Data Out) timing could be applied.
759 * The GPMI implements a feedback read strobe to sample the read data.
760 * The feedback read strobe can be delayed to support the nand EDO timing
761 * where the read strobe may deasserts before the read data is valid, and
762 * read data is valid for some time after read strobe.
763 *
764 * The following figure illustrates some aspects of a NAND Flash read:
765 *
766 * |<---tREA---->|
767 * | |
768 * | | |
769 * |<--tRP-->| |
770 * | | |
771 * __ ___|__________________________________
772 * RDN \________/ |
773 * |
774 * /---------\
775 * Read Data --------------< >---------
776 * \---------/
777 * | |
778 * |<-D->|
779 * FeedbackRDN ________ ____________
780 * \___________/
781 *
782 * D stands for delay, set in the HW_GPMI_CTRL1:RDN_DELAY.
783 *
784 *
785 * <4> Now, we begin to describe how to compute the right RDN_DELAY.
786 *
787 * 4.1) From the aspect of the nand chip pins:
788 * Delay = (tREA + C - tRP) {1}
789 *
790 * tREA : the maximum read access time. From the ONFI nand standards,
791 * we know that tREA is 16ns in mode 5, tREA is 20ns is mode 4.
792 * Please check it in : www.onfi.org
793 * C : a constant for adjust the delay. default is 4.
794 * tRP : the read pulse width.
795 * Specified by the HW_GPMI_TIMING0:DATA_SETUP:
796 * tRP = (GPMI-clock-period) * DATA_SETUP
797 *
798 * 4.2) From the aspect of the GPMI nand controller:
799 * Delay = RDN_DELAY * 0.125 * RP {2}
800 *
801 * RP : the DLL reference period.
802 * if (GPMI-clock-period > DLL_THRETHOLD)
803 * RP = GPMI-clock-period / 2;
804 * else
805 * RP = GPMI-clock-period;
806 *
807 * Set the HW_GPMI_CTRL1:HALF_PERIOD if GPMI-clock-period
808 * is greater DLL_THRETHOLD. In other SOCs, the DLL_THRETHOLD
809 * is 16ns, but in mx6q, we use 12ns.
810 *
811 * 4.3) since {1} equals {2}, we get:
812 *
813 * (tREA + 4 - tRP) * 8
814 * RDN_DELAY = --------------------- {3}
815 * RP
816 *
817 * 4.4) We only support the fastest asynchronous mode of ONFI nand.
818 * For some ONFI nand, the mode 4 is the fastest mode;
819 * while for some ONFI nand, the mode 5 is the fastest mode.
820 * So we only support the mode 4 and mode 5. It is no need to
821 * support other modes.
822 */
823static void gpmi_compute_edo_timing(struct gpmi_nand_data *this,
824 struct gpmi_nfc_hardware_timing *hw)
825{
826 struct resources *r = &this->resources;
827 unsigned long rate = clk_get_rate(r->clock[0]);
828 int mode = this->timing_mode;
829 int dll_threshold = 16; /* in ns */
830 unsigned long delay;
831 unsigned long clk_period;
832 int t_rea;
833 int c = 4;
834 int t_rp;
835 int rp;
836
837 /*
838 * [1] for GPMI_HW_GPMI_TIMING0:
839 * The async mode requires 40MHz for mode 4, 50MHz for mode 5.
840 * The GPMI can support 100MHz at most. So if we want to
841 * get the 40MHz or 50MHz, we have to set DS=1, DH=1.
842 * Set the ADDRESS_SETUP to 0 in mode 4.
843 */
844 hw->data_setup_in_cycles = 1;
845 hw->data_hold_in_cycles = 1;
846 hw->address_setup_in_cycles = ((mode == 5) ? 1 : 0);
847
848 /* [2] for GPMI_HW_GPMI_TIMING1 */
849 hw->device_busy_timeout = 0x9000;
850
851 /* [3] for GPMI_HW_GPMI_CTRL1 */
852 hw->wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY;
853
854 if (GPMI_IS_MX6Q(this))
855 dll_threshold = 12;
856
857 /*
858 * Enlarge 10 times for the numerator and denominator in {3}.
859 * This make us to get more accurate result.
860 */
861 clk_period = NSEC_PER_SEC / (rate / 10);
862 dll_threshold *= 10;
863 t_rea = ((mode == 5) ? 16 : 20) * 10;
864 c *= 10;
865
866 t_rp = clk_period * 1; /* DATA_SETUP is 1 */
867
868 if (clk_period > dll_threshold) {
869 hw->use_half_periods = 1;
870 rp = clk_period / 2;
871 } else {
872 hw->use_half_periods = 0;
873 rp = clk_period;
874 }
875
876 /*
877 * Multiply the numerator with 10, we could do a round off:
878 * 7.8 round up to 8; 7.4 round down to 7.
879 */
880 delay = (((t_rea + c - t_rp) * 8) * 10) / rp;
881 delay = (delay + 5) / 10;
882
883 hw->sample_delay_factor = delay;
884}
885
886static int enable_edo_mode(struct gpmi_nand_data *this, int mode)
887{
888 struct resources *r = &this->resources;
889 struct nand_chip *nand = &this->nand;
890 struct mtd_info *mtd = &this->mtd;
891 uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {};
892 unsigned long rate;
893 int ret;
894
895 nand->select_chip(mtd, 0);
896
897 /* [1] send SET FEATURE commond to NAND */
898 feature[0] = mode;
899 ret = nand->onfi_set_features(mtd, nand,
900 ONFI_FEATURE_ADDR_TIMING_MODE, feature);
901 if (ret)
902 goto err_out;
903
904 /* [2] send GET FEATURE command to double-check the timing mode */
905 memset(feature, 0, ONFI_SUBFEATURE_PARAM_LEN);
906 ret = nand->onfi_get_features(mtd, nand,
907 ONFI_FEATURE_ADDR_TIMING_MODE, feature);
908 if (ret || feature[0] != mode)
909 goto err_out;
910
911 nand->select_chip(mtd, -1);
912
913 /* [3] set the main IO clock, 100MHz for mode 5, 80MHz for mode 4. */
914 rate = (mode == 5) ? 100000000 : 80000000;
915 clk_set_rate(r->clock[0], rate);
916
917 this->flags |= GPMI_ASYNC_EDO_ENABLED;
918 this->timing_mode = mode;
919 dev_info(this->dev, "enable the asynchronous EDO mode %d\n", mode);
920 return 0;
921
922err_out:
923 nand->select_chip(mtd, -1);
924 dev_err(this->dev, "mode:%d ,failed in set feature.\n", mode);
925 return -EINVAL;
926}
927
928int gpmi_extra_init(struct gpmi_nand_data *this)
929{
930 struct nand_chip *chip = &this->nand;
931
932 /* Enable the asynchronous EDO feature. */
933 if (GPMI_IS_MX6Q(this) && chip->onfi_version) {
934 int mode = onfi_get_async_timing_mode(chip);
935
936 /* We only support the timing mode 4 and mode 5. */
937 if (mode & ONFI_TIMING_MODE_5)
938 mode = 5;
939 else if (mode & ONFI_TIMING_MODE_4)
940 mode = 4;
941 else
942 return 0;
943
944 return enable_edo_mode(this, mode);
945 }
946 return 0;
947}
948
740/* Begin the I/O */ 949/* Begin the I/O */
741void gpmi_begin(struct gpmi_nand_data *this) 950void gpmi_begin(struct gpmi_nand_data *this)
742{ 951{
@@ -755,7 +964,10 @@ void gpmi_begin(struct gpmi_nand_data *this)
755 goto err_out; 964 goto err_out;
756 } 965 }
757 966
758 gpmi_nfc_compute_hardware_timing(this, &hw); 967 if (this->flags & GPMI_ASYNC_EDO_ENABLED)
968 gpmi_compute_edo_timing(this, &hw);
969 else
970 gpmi_nfc_compute_hardware_timing(this, &hw);
759 971
760 /* [1] Set HW_GPMI_TIMING0 */ 972 /* [1] Set HW_GPMI_TIMING0 */
761 reg = BF_GPMI_TIMING0_ADDRESS_SETUP(hw.address_setup_in_cycles) | 973 reg = BF_GPMI_TIMING0_ADDRESS_SETUP(hw.address_setup_in_cycles) |
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 2bfd44876f81..d79696b2f19b 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -1517,6 +1517,14 @@ static int gpmi_scan_bbt(struct mtd_info *mtd)
1517 if (ret) 1517 if (ret)
1518 return ret; 1518 return ret;
1519 1519
1520 /*
1521 * Can we enable the extra features? such as EDO or Sync mode.
1522 *
1523 * We do not check the return value now. That's means if we fail in
1524 * enable the extra features, we still can run in the normal way.
1525 */
1526 gpmi_extra_init(this);
1527
1520 /* use the default BBT implementation */ 1528 /* use the default BBT implementation */
1521 return nand_default_bbt(mtd); 1529 return nand_default_bbt(mtd);
1522} 1530}
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
index 5c11e761a32e..5b6d546711a6 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
@@ -122,6 +122,10 @@ struct nand_timing {
122}; 122};
123 123
124struct gpmi_nand_data { 124struct gpmi_nand_data {
125 /* flags */
126#define GPMI_ASYNC_EDO_ENABLED (1 << 0)
127 int flags;
128
125 /* System Interface */ 129 /* System Interface */
126 struct device *dev; 130 struct device *dev;
127 struct platform_device *pdev; 131 struct platform_device *pdev;
@@ -132,6 +136,7 @@ struct gpmi_nand_data {
132 136
133 /* Flash Hardware */ 137 /* Flash Hardware */
134 struct nand_timing timing; 138 struct nand_timing timing;
139 int timing_mode;
135 140
136 /* BCH */ 141 /* BCH */
137 struct bch_geometry bch_geometry; 142 struct bch_geometry bch_geometry;
@@ -259,6 +264,7 @@ extern int start_dma_with_bch_irq(struct gpmi_nand_data *,
259 264
260/* GPMI-NAND helper function library */ 265/* GPMI-NAND helper function library */
261extern int gpmi_init(struct gpmi_nand_data *); 266extern int gpmi_init(struct gpmi_nand_data *);
267extern int gpmi_extra_init(struct gpmi_nand_data *);
262extern void gpmi_clear_bch(struct gpmi_nand_data *); 268extern void gpmi_clear_bch(struct gpmi_nand_data *);
263extern void gpmi_dump_info(struct gpmi_nand_data *); 269extern void gpmi_dump_info(struct gpmi_nand_data *);
264extern int bch_set_geometry(struct gpmi_nand_data *); 270extern int bch_set_geometry(struct gpmi_nand_data *);