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>
This commit is contained in:
parent
390e9eacf1
commit
91f5498ebf
4 changed files with 28 additions and 15 deletions
|
@ -54,7 +54,7 @@
|
||||||
#define MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0 11
|
#define MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0 11
|
||||||
#define MX6Q_BM_BCH_FLASH0LAYOUT0_ECC0 (0x1f << MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0)
|
#define MX6Q_BM_BCH_FLASH0LAYOUT0_ECC0 (0x1f << MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0)
|
||||||
#define BF_BCH_FLASH0LAYOUT0_ECC0(v, x) \
|
#define BF_BCH_FLASH0LAYOUT0_ECC0(v, x) \
|
||||||
(GPMI_IS_MX6Q(x) \
|
(GPMI_IS_MX6(x) \
|
||||||
? (((v) << MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0) \
|
? (((v) << MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0) \
|
||||||
& MX6Q_BM_BCH_FLASH0LAYOUT0_ECC0) \
|
& MX6Q_BM_BCH_FLASH0LAYOUT0_ECC0) \
|
||||||
: (((v) << BP_BCH_FLASH0LAYOUT0_ECC0) \
|
: (((v) << BP_BCH_FLASH0LAYOUT0_ECC0) \
|
||||||
|
@ -65,7 +65,7 @@
|
||||||
#define MX6Q_BM_BCH_FLASH0LAYOUT0_GF_13_14 \
|
#define MX6Q_BM_BCH_FLASH0LAYOUT0_GF_13_14 \
|
||||||
(0x1 << MX6Q_BP_BCH_FLASH0LAYOUT0_GF_13_14)
|
(0x1 << MX6Q_BP_BCH_FLASH0LAYOUT0_GF_13_14)
|
||||||
#define BF_BCH_FLASH0LAYOUT0_GF(v, x) \
|
#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) \
|
? (((1) << MX6Q_BP_BCH_FLASH0LAYOUT0_GF_13_14) \
|
||||||
& MX6Q_BM_BCH_FLASH0LAYOUT0_GF_13_14) \
|
& MX6Q_BM_BCH_FLASH0LAYOUT0_GF_13_14) \
|
||||||
: 0 \
|
: 0 \
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
#define MX6Q_BM_BCH_FLASH0LAYOUT0_DATA0_SIZE \
|
#define MX6Q_BM_BCH_FLASH0LAYOUT0_DATA0_SIZE \
|
||||||
(0x3ff << BP_BCH_FLASH0LAYOUT0_DATA0_SIZE)
|
(0x3ff << BP_BCH_FLASH0LAYOUT0_DATA0_SIZE)
|
||||||
#define BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(v, x) \
|
#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) >> 2) & MX6Q_BM_BCH_FLASH0LAYOUT0_DATA0_SIZE) \
|
||||||
: ((v) & BM_BCH_FLASH0LAYOUT0_DATA0_SIZE) \
|
: ((v) & BM_BCH_FLASH0LAYOUT0_DATA0_SIZE) \
|
||||||
)
|
)
|
||||||
|
@ -96,7 +96,7 @@
|
||||||
#define MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN 11
|
#define MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN 11
|
||||||
#define MX6Q_BM_BCH_FLASH0LAYOUT1_ECCN (0x1f << MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN)
|
#define MX6Q_BM_BCH_FLASH0LAYOUT1_ECCN (0x1f << MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN)
|
||||||
#define BF_BCH_FLASH0LAYOUT1_ECCN(v, x) \
|
#define BF_BCH_FLASH0LAYOUT1_ECCN(v, x) \
|
||||||
(GPMI_IS_MX6Q(x) \
|
(GPMI_IS_MX6(x) \
|
||||||
? (((v) << MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN) \
|
? (((v) << MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN) \
|
||||||
& MX6Q_BM_BCH_FLASH0LAYOUT1_ECCN) \
|
& MX6Q_BM_BCH_FLASH0LAYOUT1_ECCN) \
|
||||||
: (((v) << BP_BCH_FLASH0LAYOUT1_ECCN) \
|
: (((v) << BP_BCH_FLASH0LAYOUT1_ECCN) \
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
#define MX6Q_BM_BCH_FLASH0LAYOUT1_GF_13_14 \
|
#define MX6Q_BM_BCH_FLASH0LAYOUT1_GF_13_14 \
|
||||||
(0x1 << MX6Q_BP_BCH_FLASH0LAYOUT1_GF_13_14)
|
(0x1 << MX6Q_BP_BCH_FLASH0LAYOUT1_GF_13_14)
|
||||||
#define BF_BCH_FLASH0LAYOUT1_GF(v, x) \
|
#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) \
|
? (((1) << MX6Q_BP_BCH_FLASH0LAYOUT1_GF_13_14) \
|
||||||
& MX6Q_BM_BCH_FLASH0LAYOUT1_GF_13_14) \
|
& MX6Q_BM_BCH_FLASH0LAYOUT1_GF_13_14) \
|
||||||
: 0 \
|
: 0 \
|
||||||
|
@ -119,7 +119,7 @@
|
||||||
#define MX6Q_BM_BCH_FLASH0LAYOUT1_DATAN_SIZE \
|
#define MX6Q_BM_BCH_FLASH0LAYOUT1_DATAN_SIZE \
|
||||||
(0x3ff << BP_BCH_FLASH0LAYOUT1_DATAN_SIZE)
|
(0x3ff << BP_BCH_FLASH0LAYOUT1_DATAN_SIZE)
|
||||||
#define BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(v, x) \
|
#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) >> 2) & MX6Q_BM_BCH_FLASH0LAYOUT1_DATAN_SIZE) \
|
||||||
: ((v) & BM_BCH_FLASH0LAYOUT1_DATAN_SIZE) \
|
: ((v) & BM_BCH_FLASH0LAYOUT1_DATAN_SIZE) \
|
||||||
)
|
)
|
||||||
|
|
|
@ -971,7 +971,7 @@ int gpmi_extra_init(struct gpmi_nand_data *this)
|
||||||
struct nand_chip *chip = &this->nand;
|
struct nand_chip *chip = &this->nand;
|
||||||
|
|
||||||
/* Enable the asynchronous EDO feature. */
|
/* 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);
|
int mode = onfi_get_async_timing_mode(chip);
|
||||||
|
|
||||||
/* We only support the timing mode 4 and mode 5. */
|
/* 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)) {
|
if (GPMI_IS_MX23(this)) {
|
||||||
mask = MX23_BM_GPMI_DEBUG_READY0 << chip;
|
mask = MX23_BM_GPMI_DEBUG_READY0 << chip;
|
||||||
reg = readl(r->gpmi_regs + HW_GPMI_DEBUG);
|
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
|
* In the imx6, all the ready/busy pins are bound
|
||||||
* together. So we only need to check chip 0.
|
* together. So we only need to check chip 0.
|
||||||
*/
|
*/
|
||||||
if (GPMI_IS_MX6Q(this))
|
if (GPMI_IS_MX6(this))
|
||||||
chip = 0;
|
chip = 0;
|
||||||
|
|
||||||
/* MX28 shares the same R/B register as MX6Q. */
|
/* MX28 shares the same R/B register as MX6Q. */
|
||||||
|
|
|
@ -71,6 +71,12 @@ static const struct gpmi_devdata gpmi_devdata_imx6q = {
|
||||||
.max_chain_delay = 12,
|
.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)
|
static irqreturn_t bch_irq(int irq, void *cookie)
|
||||||
{
|
{
|
||||||
struct gpmi_nand_data *this = cookie;
|
struct gpmi_nand_data *this = cookie;
|
||||||
|
@ -583,7 +589,7 @@ static int gpmi_get_clks(struct gpmi_nand_data *this)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get extra clocks */
|
/* Get extra clocks */
|
||||||
if (GPMI_IS_MX6Q(this))
|
if (GPMI_IS_MX6(this))
|
||||||
extra_clks = extra_clks_for_mx6q;
|
extra_clks = extra_clks_for_mx6q;
|
||||||
if (!extra_clks)
|
if (!extra_clks)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -601,9 +607,9 @@ static int gpmi_get_clks(struct gpmi_nand_data *this)
|
||||||
r->clock[i] = clk;
|
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
|
* If you want to use the ONFI nand which is in the
|
||||||
* Synchronous Mode, you should change the clock as you need.
|
* 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
|
* (1) the chip is imx6, and
|
||||||
* (2) the size of the ECC parity is byte aligned.
|
* (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) {
|
((bch_geo->gf_len * bch_geo->ecc_strength) % 8) == 0) {
|
||||||
ecc->read_subpage = gpmi_ecc_read_subpage;
|
ecc->read_subpage = gpmi_ecc_read_subpage;
|
||||||
chip->options |= NAND_SUBPAGE_READ;
|
chip->options |= NAND_SUBPAGE_READ;
|
||||||
|
@ -1722,7 +1728,7 @@ static int gpmi_nand_init(struct gpmi_nand_data *this)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_out;
|
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)
|
if (ret)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
|
||||||
|
@ -1761,6 +1767,9 @@ static const struct of_device_id gpmi_nand_id_table[] = {
|
||||||
}, {
|
}, {
|
||||||
.compatible = "fsl,imx6q-gpmi-nand",
|
.compatible = "fsl,imx6q-gpmi-nand",
|
||||||
.data = (void *)&gpmi_devdata_imx6q,
|
.data = (void *)&gpmi_devdata_imx6q,
|
||||||
|
}, {
|
||||||
|
.compatible = "fsl,imx6sx-gpmi-nand",
|
||||||
|
.data = (void *)&gpmi_devdata_imx6sx,
|
||||||
}, {}
|
}, {}
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, gpmi_nand_id_table);
|
MODULE_DEVICE_TABLE(of, gpmi_nand_id_table);
|
||||||
|
|
|
@ -122,7 +122,8 @@ struct nand_timing {
|
||||||
enum gpmi_type {
|
enum gpmi_type {
|
||||||
IS_MX23,
|
IS_MX23,
|
||||||
IS_MX28,
|
IS_MX28,
|
||||||
IS_MX6Q
|
IS_MX6Q,
|
||||||
|
IS_MX6SX
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gpmi_devdata {
|
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_MX23(x) ((x)->devdata->type == IS_MX23)
|
||||||
#define GPMI_IS_MX28(x) ((x)->devdata->type == IS_MX28)
|
#define GPMI_IS_MX28(x) ((x)->devdata->type == IS_MX28)
|
||||||
#define GPMI_IS_MX6Q(x) ((x)->devdata->type == IS_MX6Q)
|
#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
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue