aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHuang Shijie <b32955@freescale.com>2014-03-26 22:43:22 -0400
committerBrian Norris <computersforpeace@gmail.com>2014-05-28 19:02:16 -0400
commit91f5498ebfb2352ed6b5eb2780adcfe019961565 (patch)
treec2eb5107cb99dc328901184b0d60ba36d0c48115
parent390e9eacf1dcece3cee8fb4d95edbfea90574e91 (diff)
mtd: gpmi: add gpmi support for imx6sx
The gpmi's IP for imx6sx is nearly the same as the gpmi's IP for imx6q, except the following two new features: (1) the new BCH contoller has 62-BIT correcting ECC strength (The BCH for imx6q only has 40-BIT ECC strength). (2) add the hardware Randomizer support. This patch does the follow changes: (1) add a new macro GPMI_IS_MX6SX to represent the imx6sx's gpmi. (2) add a new macro GPMI_IS_MX6. We use this macro to initialize the same registers for both imx6sx and imx6q, and so on. (3) add a new gpmi_devdata instance, the gpmi_devdata_imx6sx, for imx6sx. Signed-off-by: Huang Shijie <b32955@freescale.com> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
-rw-r--r--drivers/mtd/nand/gpmi-nand/bch-regs.h12
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-lib.c6
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.c19
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.h6
4 files changed, 28 insertions, 15 deletions
diff --git a/drivers/mtd/nand/gpmi-nand/bch-regs.h b/drivers/mtd/nand/gpmi-nand/bch-regs.h
index 588f5374047c..05bb91f2f4c4 100644
--- a/drivers/mtd/nand/gpmi-nand/bch-regs.h
+++ b/drivers/mtd/nand/gpmi-nand/bch-regs.h
@@ -54,7 +54,7 @@
54#define MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0 11 54#define MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0 11
55#define MX6Q_BM_BCH_FLASH0LAYOUT0_ECC0 (0x1f << MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0) 55#define MX6Q_BM_BCH_FLASH0LAYOUT0_ECC0 (0x1f << MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0)
56#define BF_BCH_FLASH0LAYOUT0_ECC0(v, x) \ 56#define BF_BCH_FLASH0LAYOUT0_ECC0(v, x) \
57 (GPMI_IS_MX6Q(x) \ 57 (GPMI_IS_MX6(x) \
58 ? (((v) << MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0) \ 58 ? (((v) << MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0) \
59 & MX6Q_BM_BCH_FLASH0LAYOUT0_ECC0) \ 59 & MX6Q_BM_BCH_FLASH0LAYOUT0_ECC0) \
60 : (((v) << BP_BCH_FLASH0LAYOUT0_ECC0) \ 60 : (((v) << BP_BCH_FLASH0LAYOUT0_ECC0) \
@@ -65,7 +65,7 @@
65#define MX6Q_BM_BCH_FLASH0LAYOUT0_GF_13_14 \ 65#define MX6Q_BM_BCH_FLASH0LAYOUT0_GF_13_14 \
66 (0x1 << MX6Q_BP_BCH_FLASH0LAYOUT0_GF_13_14) 66 (0x1 << MX6Q_BP_BCH_FLASH0LAYOUT0_GF_13_14)
67#define BF_BCH_FLASH0LAYOUT0_GF(v, x) \ 67#define BF_BCH_FLASH0LAYOUT0_GF(v, x) \
68 ((GPMI_IS_MX6Q(x) && ((v) == 14)) \ 68 ((GPMI_IS_MX6(x) && ((v) == 14)) \
69 ? (((1) << MX6Q_BP_BCH_FLASH0LAYOUT0_GF_13_14) \ 69 ? (((1) << MX6Q_BP_BCH_FLASH0LAYOUT0_GF_13_14) \
70 & MX6Q_BM_BCH_FLASH0LAYOUT0_GF_13_14) \ 70 & MX6Q_BM_BCH_FLASH0LAYOUT0_GF_13_14) \
71 : 0 \ 71 : 0 \
@@ -77,7 +77,7 @@
77#define MX6Q_BM_BCH_FLASH0LAYOUT0_DATA0_SIZE \ 77#define MX6Q_BM_BCH_FLASH0LAYOUT0_DATA0_SIZE \
78 (0x3ff << BP_BCH_FLASH0LAYOUT0_DATA0_SIZE) 78 (0x3ff << BP_BCH_FLASH0LAYOUT0_DATA0_SIZE)
79#define BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(v, x) \ 79#define BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(v, x) \
80 (GPMI_IS_MX6Q(x) \ 80 (GPMI_IS_MX6(x) \
81 ? (((v) >> 2) & MX6Q_BM_BCH_FLASH0LAYOUT0_DATA0_SIZE) \ 81 ? (((v) >> 2) & MX6Q_BM_BCH_FLASH0LAYOUT0_DATA0_SIZE) \
82 : ((v) & BM_BCH_FLASH0LAYOUT0_DATA0_SIZE) \ 82 : ((v) & BM_BCH_FLASH0LAYOUT0_DATA0_SIZE) \
83 ) 83 )
@@ -96,7 +96,7 @@
96#define MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN 11 96#define MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN 11
97#define MX6Q_BM_BCH_FLASH0LAYOUT1_ECCN (0x1f << MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN) 97#define MX6Q_BM_BCH_FLASH0LAYOUT1_ECCN (0x1f << MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN)
98#define BF_BCH_FLASH0LAYOUT1_ECCN(v, x) \ 98#define BF_BCH_FLASH0LAYOUT1_ECCN(v, x) \
99 (GPMI_IS_MX6Q(x) \ 99 (GPMI_IS_MX6(x) \
100 ? (((v) << MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN) \ 100 ? (((v) << MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN) \
101 & MX6Q_BM_BCH_FLASH0LAYOUT1_ECCN) \ 101 & MX6Q_BM_BCH_FLASH0LAYOUT1_ECCN) \
102 : (((v) << BP_BCH_FLASH0LAYOUT1_ECCN) \ 102 : (((v) << BP_BCH_FLASH0LAYOUT1_ECCN) \
@@ -107,7 +107,7 @@
107#define MX6Q_BM_BCH_FLASH0LAYOUT1_GF_13_14 \ 107#define MX6Q_BM_BCH_FLASH0LAYOUT1_GF_13_14 \
108 (0x1 << MX6Q_BP_BCH_FLASH0LAYOUT1_GF_13_14) 108 (0x1 << MX6Q_BP_BCH_FLASH0LAYOUT1_GF_13_14)
109#define BF_BCH_FLASH0LAYOUT1_GF(v, x) \ 109#define BF_BCH_FLASH0LAYOUT1_GF(v, x) \
110 ((GPMI_IS_MX6Q(x) && ((v) == 14)) \ 110 ((GPMI_IS_MX6(x) && ((v) == 14)) \
111 ? (((1) << MX6Q_BP_BCH_FLASH0LAYOUT1_GF_13_14) \ 111 ? (((1) << MX6Q_BP_BCH_FLASH0LAYOUT1_GF_13_14) \
112 & MX6Q_BM_BCH_FLASH0LAYOUT1_GF_13_14) \ 112 & MX6Q_BM_BCH_FLASH0LAYOUT1_GF_13_14) \
113 : 0 \ 113 : 0 \
@@ -119,7 +119,7 @@
119#define MX6Q_BM_BCH_FLASH0LAYOUT1_DATAN_SIZE \ 119#define MX6Q_BM_BCH_FLASH0LAYOUT1_DATAN_SIZE \
120 (0x3ff << BP_BCH_FLASH0LAYOUT1_DATAN_SIZE) 120 (0x3ff << BP_BCH_FLASH0LAYOUT1_DATAN_SIZE)
121#define BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(v, x) \ 121#define BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(v, x) \
122 (GPMI_IS_MX6Q(x) \ 122 (GPMI_IS_MX6(x) \
123 ? (((v) >> 2) & MX6Q_BM_BCH_FLASH0LAYOUT1_DATAN_SIZE) \ 123 ? (((v) >> 2) & MX6Q_BM_BCH_FLASH0LAYOUT1_DATAN_SIZE) \
124 : ((v) & BM_BCH_FLASH0LAYOUT1_DATAN_SIZE) \ 124 : ((v) & BM_BCH_FLASH0LAYOUT1_DATAN_SIZE) \
125 ) 125 )
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
index ec4db2a359e5..87e658ce23ef 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
@@ -971,7 +971,7 @@ int gpmi_extra_init(struct gpmi_nand_data *this)
971 struct nand_chip *chip = &this->nand; 971 struct nand_chip *chip = &this->nand;
972 972
973 /* Enable the asynchronous EDO feature. */ 973 /* Enable the asynchronous EDO feature. */
974 if (GPMI_IS_MX6Q(this) && chip->onfi_version) { 974 if (GPMI_IS_MX6(this) && chip->onfi_version) {
975 int mode = onfi_get_async_timing_mode(chip); 975 int mode = onfi_get_async_timing_mode(chip);
976 976
977 /* We only support the timing mode 4 and mode 5. */ 977 /* We only support the timing mode 4 and mode 5. */
@@ -1093,12 +1093,12 @@ int gpmi_is_ready(struct gpmi_nand_data *this, unsigned chip)
1093 if (GPMI_IS_MX23(this)) { 1093 if (GPMI_IS_MX23(this)) {
1094 mask = MX23_BM_GPMI_DEBUG_READY0 << chip; 1094 mask = MX23_BM_GPMI_DEBUG_READY0 << chip;
1095 reg = readl(r->gpmi_regs + HW_GPMI_DEBUG); 1095 reg = readl(r->gpmi_regs + HW_GPMI_DEBUG);
1096 } else if (GPMI_IS_MX28(this) || GPMI_IS_MX6Q(this)) { 1096 } else if (GPMI_IS_MX28(this) || GPMI_IS_MX6(this)) {
1097 /* 1097 /*
1098 * In the imx6, all the ready/busy pins are bound 1098 * In the imx6, all the ready/busy pins are bound
1099 * together. So we only need to check chip 0. 1099 * together. So we only need to check chip 0.
1100 */ 1100 */
1101 if (GPMI_IS_MX6Q(this)) 1101 if (GPMI_IS_MX6(this))
1102 chip = 0; 1102 chip = 0;
1103 1103
1104 /* MX28 shares the same R/B register as MX6Q. */ 1104 /* MX28 shares the same R/B register as MX6Q. */
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index e88d64e1e963..f638cd8077ca 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -71,6 +71,12 @@ static const struct gpmi_devdata gpmi_devdata_imx6q = {
71 .max_chain_delay = 12, 71 .max_chain_delay = 12,
72}; 72};
73 73
74static const struct gpmi_devdata gpmi_devdata_imx6sx = {
75 .type = IS_MX6SX,
76 .bch_max_ecc_strength = 62,
77 .max_chain_delay = 12,
78};
79
74static irqreturn_t bch_irq(int irq, void *cookie) 80static irqreturn_t bch_irq(int irq, void *cookie)
75{ 81{
76 struct gpmi_nand_data *this = cookie; 82 struct gpmi_nand_data *this = cookie;
@@ -583,7 +589,7 @@ static int gpmi_get_clks(struct gpmi_nand_data *this)
583 } 589 }
584 590
585 /* Get extra clocks */ 591 /* Get extra clocks */
586 if (GPMI_IS_MX6Q(this)) 592 if (GPMI_IS_MX6(this))
587 extra_clks = extra_clks_for_mx6q; 593 extra_clks = extra_clks_for_mx6q;
588 if (!extra_clks) 594 if (!extra_clks)
589 return 0; 595 return 0;
@@ -601,9 +607,9 @@ static int gpmi_get_clks(struct gpmi_nand_data *this)
601 r->clock[i] = clk; 607 r->clock[i] = clk;
602 } 608 }
603 609
604 if (GPMI_IS_MX6Q(this)) 610 if (GPMI_IS_MX6(this))
605 /* 611 /*
606 * Set the default value for the gpmi clock in mx6q: 612 * Set the default value for the gpmi clock.
607 * 613 *
608 * If you want to use the ONFI nand which is in the 614 * If you want to use the ONFI nand which is in the
609 * Synchronous Mode, you should change the clock as you need. 615 * Synchronous Mode, you should change the clock as you need.
@@ -1666,7 +1672,7 @@ static int gpmi_init_last(struct gpmi_nand_data *this)
1666 * (1) the chip is imx6, and 1672 * (1) the chip is imx6, and
1667 * (2) the size of the ECC parity is byte aligned. 1673 * (2) the size of the ECC parity is byte aligned.
1668 */ 1674 */
1669 if (GPMI_IS_MX6Q(this) && 1675 if (GPMI_IS_MX6(this) &&
1670 ((bch_geo->gf_len * bch_geo->ecc_strength) % 8) == 0) { 1676 ((bch_geo->gf_len * bch_geo->ecc_strength) % 8) == 0) {
1671 ecc->read_subpage = gpmi_ecc_read_subpage; 1677 ecc->read_subpage = gpmi_ecc_read_subpage;
1672 chip->options |= NAND_SUBPAGE_READ; 1678 chip->options |= NAND_SUBPAGE_READ;
@@ -1722,7 +1728,7 @@ static int gpmi_nand_init(struct gpmi_nand_data *this)
1722 if (ret) 1728 if (ret)
1723 goto err_out; 1729 goto err_out;
1724 1730
1725 ret = nand_scan_ident(mtd, GPMI_IS_MX6Q(this) ? 2 : 1, NULL); 1731 ret = nand_scan_ident(mtd, GPMI_IS_MX6(this) ? 2 : 1, NULL);
1726 if (ret) 1732 if (ret)
1727 goto err_out; 1733 goto err_out;
1728 1734
@@ -1761,6 +1767,9 @@ static const struct of_device_id gpmi_nand_id_table[] = {
1761 }, { 1767 }, {
1762 .compatible = "fsl,imx6q-gpmi-nand", 1768 .compatible = "fsl,imx6q-gpmi-nand",
1763 .data = (void *)&gpmi_devdata_imx6q, 1769 .data = (void *)&gpmi_devdata_imx6q,
1770 }, {
1771 .compatible = "fsl,imx6sx-gpmi-nand",
1772 .data = (void *)&gpmi_devdata_imx6sx,
1764 }, {} 1773 }, {}
1765}; 1774};
1766MODULE_DEVICE_TABLE(of, gpmi_nand_id_table); 1775MODULE_DEVICE_TABLE(of, gpmi_nand_id_table);
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
index 7904e8329b67..32c6ba49f986 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
@@ -122,7 +122,8 @@ struct nand_timing {
122enum gpmi_type { 122enum gpmi_type {
123 IS_MX23, 123 IS_MX23,
124 IS_MX28, 124 IS_MX28,
125 IS_MX6Q 125 IS_MX6Q,
126 IS_MX6SX
126}; 127};
127 128
128struct gpmi_devdata { 129struct gpmi_devdata {
@@ -298,4 +299,7 @@ extern int gpmi_read_page(struct gpmi_nand_data *,
298#define GPMI_IS_MX23(x) ((x)->devdata->type == IS_MX23) 299#define GPMI_IS_MX23(x) ((x)->devdata->type == IS_MX23)
299#define GPMI_IS_MX28(x) ((x)->devdata->type == IS_MX28) 300#define GPMI_IS_MX28(x) ((x)->devdata->type == IS_MX28)
300#define GPMI_IS_MX6Q(x) ((x)->devdata->type == IS_MX6Q) 301#define GPMI_IS_MX6Q(x) ((x)->devdata->type == IS_MX6Q)
302#define GPMI_IS_MX6SX(x) ((x)->devdata->type == IS_MX6SX)
303
304#define GPMI_IS_MX6(x) (GPMI_IS_MX6Q(x) || GPMI_IS_MX6SX(x))
301#endif 305#endif