From 91f5498ebfb2352ed6b5eb2780adcfe019961565 Mon Sep 17 00:00:00 2001 From: Huang Shijie Date: Thu, 27 Mar 2014 10:43:22 +0800 Subject: 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 Signed-off-by: Brian Norris --- drivers/mtd/nand/gpmi-nand/bch-regs.h | 12 ++++++------ drivers/mtd/nand/gpmi-nand/gpmi-lib.c | 6 +++--- drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 19 ++++++++++++++----- drivers/mtd/nand/gpmi-nand/gpmi-nand.h | 6 +++++- 4 files changed, 28 insertions(+), 15 deletions(-) (limited to 'drivers') 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 @@ #define MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0 11 #define MX6Q_BM_BCH_FLASH0LAYOUT0_ECC0 (0x1f << MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0) #define BF_BCH_FLASH0LAYOUT0_ECC0(v, x) \ - (GPMI_IS_MX6Q(x) \ + (GPMI_IS_MX6(x) \ ? (((v) << MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0) \ & MX6Q_BM_BCH_FLASH0LAYOUT0_ECC0) \ : (((v) << BP_BCH_FLASH0LAYOUT0_ECC0) \ @@ -65,7 +65,7 @@ #define MX6Q_BM_BCH_FLASH0LAYOUT0_GF_13_14 \ (0x1 << MX6Q_BP_BCH_FLASH0LAYOUT0_GF_13_14) #define BF_BCH_FLASH0LAYOUT0_GF(v, x) \ - ((GPMI_IS_MX6Q(x) && ((v) == 14)) \ + ((GPMI_IS_MX6(x) && ((v) == 14)) \ ? (((1) << MX6Q_BP_BCH_FLASH0LAYOUT0_GF_13_14) \ & MX6Q_BM_BCH_FLASH0LAYOUT0_GF_13_14) \ : 0 \ @@ -77,7 +77,7 @@ #define MX6Q_BM_BCH_FLASH0LAYOUT0_DATA0_SIZE \ (0x3ff << BP_BCH_FLASH0LAYOUT0_DATA0_SIZE) #define BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(v, x) \ - (GPMI_IS_MX6Q(x) \ + (GPMI_IS_MX6(x) \ ? (((v) >> 2) & MX6Q_BM_BCH_FLASH0LAYOUT0_DATA0_SIZE) \ : ((v) & BM_BCH_FLASH0LAYOUT0_DATA0_SIZE) \ ) @@ -96,7 +96,7 @@ #define MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN 11 #define MX6Q_BM_BCH_FLASH0LAYOUT1_ECCN (0x1f << MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN) #define BF_BCH_FLASH0LAYOUT1_ECCN(v, x) \ - (GPMI_IS_MX6Q(x) \ + (GPMI_IS_MX6(x) \ ? (((v) << MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN) \ & MX6Q_BM_BCH_FLASH0LAYOUT1_ECCN) \ : (((v) << BP_BCH_FLASH0LAYOUT1_ECCN) \ @@ -107,7 +107,7 @@ #define MX6Q_BM_BCH_FLASH0LAYOUT1_GF_13_14 \ (0x1 << MX6Q_BP_BCH_FLASH0LAYOUT1_GF_13_14) #define BF_BCH_FLASH0LAYOUT1_GF(v, x) \ - ((GPMI_IS_MX6Q(x) && ((v) == 14)) \ + ((GPMI_IS_MX6(x) && ((v) == 14)) \ ? (((1) << MX6Q_BP_BCH_FLASH0LAYOUT1_GF_13_14) \ & MX6Q_BM_BCH_FLASH0LAYOUT1_GF_13_14) \ : 0 \ @@ -119,7 +119,7 @@ #define MX6Q_BM_BCH_FLASH0LAYOUT1_DATAN_SIZE \ (0x3ff << BP_BCH_FLASH0LAYOUT1_DATAN_SIZE) #define BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(v, x) \ - (GPMI_IS_MX6Q(x) \ + (GPMI_IS_MX6(x) \ ? (((v) >> 2) & MX6Q_BM_BCH_FLASH0LAYOUT1_DATAN_SIZE) \ : ((v) & BM_BCH_FLASH0LAYOUT1_DATAN_SIZE) \ ) 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) struct nand_chip *chip = &this->nand; /* Enable the asynchronous EDO feature. */ - if (GPMI_IS_MX6Q(this) && chip->onfi_version) { + if (GPMI_IS_MX6(this) && chip->onfi_version) { int mode = onfi_get_async_timing_mode(chip); /* 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) if (GPMI_IS_MX23(this)) { mask = MX23_BM_GPMI_DEBUG_READY0 << chip; reg = readl(r->gpmi_regs + HW_GPMI_DEBUG); - } else if (GPMI_IS_MX28(this) || GPMI_IS_MX6Q(this)) { + } else if (GPMI_IS_MX28(this) || GPMI_IS_MX6(this)) { /* * In the imx6, all the ready/busy pins are bound * together. So we only need to check chip 0. */ - if (GPMI_IS_MX6Q(this)) + if (GPMI_IS_MX6(this)) chip = 0; /* 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 = { .max_chain_delay = 12, }; +static const struct gpmi_devdata gpmi_devdata_imx6sx = { + .type = IS_MX6SX, + .bch_max_ecc_strength = 62, + .max_chain_delay = 12, +}; + static irqreturn_t bch_irq(int irq, void *cookie) { struct gpmi_nand_data *this = cookie; @@ -583,7 +589,7 @@ static int gpmi_get_clks(struct gpmi_nand_data *this) } /* Get extra clocks */ - if (GPMI_IS_MX6Q(this)) + if (GPMI_IS_MX6(this)) extra_clks = extra_clks_for_mx6q; if (!extra_clks) return 0; @@ -601,9 +607,9 @@ static int gpmi_get_clks(struct gpmi_nand_data *this) r->clock[i] = clk; } - if (GPMI_IS_MX6Q(this)) + if (GPMI_IS_MX6(this)) /* - * Set the default value for the gpmi clock in mx6q: + * Set the default value for the gpmi clock. * * If you want to use the ONFI nand which is in the * Synchronous Mode, you should change the clock as you need. @@ -1666,7 +1672,7 @@ static int gpmi_init_last(struct gpmi_nand_data *this) * (1) the chip is imx6, and * (2) the size of the ECC parity is byte aligned. */ - if (GPMI_IS_MX6Q(this) && + if (GPMI_IS_MX6(this) && ((bch_geo->gf_len * bch_geo->ecc_strength) % 8) == 0) { ecc->read_subpage = gpmi_ecc_read_subpage; chip->options |= NAND_SUBPAGE_READ; @@ -1722,7 +1728,7 @@ static int gpmi_nand_init(struct gpmi_nand_data *this) if (ret) goto err_out; - ret = nand_scan_ident(mtd, GPMI_IS_MX6Q(this) ? 2 : 1, NULL); + ret = nand_scan_ident(mtd, GPMI_IS_MX6(this) ? 2 : 1, NULL); if (ret) goto err_out; @@ -1761,6 +1767,9 @@ static const struct of_device_id gpmi_nand_id_table[] = { }, { .compatible = "fsl,imx6q-gpmi-nand", .data = (void *)&gpmi_devdata_imx6q, + }, { + .compatible = "fsl,imx6sx-gpmi-nand", + .data = (void *)&gpmi_devdata_imx6sx, }, {} }; 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 { enum gpmi_type { IS_MX23, IS_MX28, - IS_MX6Q + IS_MX6Q, + IS_MX6SX }; struct gpmi_devdata { @@ -298,4 +299,7 @@ extern int gpmi_read_page(struct gpmi_nand_data *, #define GPMI_IS_MX23(x) ((x)->devdata->type == IS_MX23) #define GPMI_IS_MX28(x) ((x)->devdata->type == IS_MX28) #define GPMI_IS_MX6Q(x) ((x)->devdata->type == IS_MX6Q) +#define GPMI_IS_MX6SX(x) ((x)->devdata->type == IS_MX6SX) + +#define GPMI_IS_MX6(x) (GPMI_IS_MX6Q(x) || GPMI_IS_MX6SX(x)) #endif -- cgit v1.2.3