diff options
author | Huang Shijie <b32955@freescale.com> | 2014-03-26 22:43:22 -0400 |
---|---|---|
committer | Brian Norris <computersforpeace@gmail.com> | 2014-05-28 19:02:16 -0400 |
commit | 91f5498ebfb2352ed6b5eb2780adcfe019961565 (patch) | |
tree | c2eb5107cb99dc328901184b0d60ba36d0c48115 | |
parent | 390e9eacf1dcece3cee8fb4d95edbfea90574e91 (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.h | 12 | ||||
-rw-r--r-- | drivers/mtd/nand/gpmi-nand/gpmi-lib.c | 6 | ||||
-rw-r--r-- | drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 19 | ||||
-rw-r--r-- | drivers/mtd/nand/gpmi-nand/gpmi-nand.h | 6 |
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 | ||
74 | static const struct gpmi_devdata gpmi_devdata_imx6sx = { | ||
75 | .type = IS_MX6SX, | ||
76 | .bch_max_ecc_strength = 62, | ||
77 | .max_chain_delay = 12, | ||
78 | }; | ||
79 | |||
74 | static irqreturn_t bch_irq(int irq, void *cookie) | 80 | static 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 | }; |
1766 | MODULE_DEVICE_TABLE(of, gpmi_nand_id_table); | 1775 | MODULE_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 { | |||
122 | enum gpmi_type { | 122 | enum 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 | ||
128 | struct gpmi_devdata { | 129 | struct 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 |