#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_MX6(x) \
+ ((GPMI_IS_MX6(x) || GPMI_IS_MX8(x)) \
? (((v) << MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0) \
& MX6Q_BM_BCH_FLASH0LAYOUT0_ECC0) \
: (((v) << BP_BCH_FLASH0LAYOUT0_ECC0) \
#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_MX6(x) && ((v) == 14)) \
+ (((GPMI_IS_MX6(x) || GPMI_IS_MX8(x)) && ((v) == 14)) \
? (((1) << MX6Q_BP_BCH_FLASH0LAYOUT0_GF_13_14) \
& MX6Q_BM_BCH_FLASH0LAYOUT0_GF_13_14) \
: 0 \
#define MX6Q_BM_BCH_FLASH0LAYOUT0_DATA0_SIZE \
(0x3ff << BP_BCH_FLASH0LAYOUT0_DATA0_SIZE)
#define BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(v, x) \
- (GPMI_IS_MX6(x) \
+ ((GPMI_IS_MX6(x) || GPMI_IS_MX8(x)) \
? (((v) >> 2) & MX6Q_BM_BCH_FLASH0LAYOUT0_DATA0_SIZE) \
: ((v) & BM_BCH_FLASH0LAYOUT0_DATA0_SIZE) \
)
#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_MX6(x) \
+ ((GPMI_IS_MX6(x) || GPMI_IS_MX8(x)) \
? (((v) << MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN) \
& MX6Q_BM_BCH_FLASH0LAYOUT1_ECCN) \
: (((v) << BP_BCH_FLASH0LAYOUT1_ECCN) \
#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_MX6(x) && ((v) == 14)) \
+ (((GPMI_IS_MX6(x) || GPMI_IS_MX8(x)) && ((v) == 14)) \
? (((1) << MX6Q_BP_BCH_FLASH0LAYOUT1_GF_13_14) \
& MX6Q_BM_BCH_FLASH0LAYOUT1_GF_13_14) \
: 0 \
#define MX6Q_BM_BCH_FLASH0LAYOUT1_DATAN_SIZE \
(0x3ff << BP_BCH_FLASH0LAYOUT1_DATAN_SIZE)
#define BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(v, x) \
- (GPMI_IS_MX6(x) \
+ ((GPMI_IS_MX6(x) || GPMI_IS_MX8(x)) \
? (((v) >> 2) & MX6Q_BM_BCH_FLASH0LAYOUT1_DATAN_SIZE) \
: ((v) & BM_BCH_FLASH0LAYOUT1_DATAN_SIZE) \
)
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_MX6(this)) {
+ } else if (GPMI_IS_MX28(this) || GPMI_IS_MX6(this) ||
+ GPMI_IS_MX8(this)) {
/*
* In the imx6, all the ready/busy pins are bound
* together. So we only need to check chip 0.
*/
- if (GPMI_IS_MX6(this))
+ if (GPMI_IS_MX6(this) || GPMI_IS_MX8(this))
chip = 0;
/* MX28 shares the same R/B register as MX6Q. */
static const struct gpmi_devdata gpmi_devdata_imx6qp = {
.type = IS_MX6QP,
.bch_max_ecc_strength = 40,
- .max_chain_delay = 12,
+ .max_chain_delay = 12000,
.clks = gpmi_clks_for_mx6,
.clks_count = ARRAY_SIZE(gpmi_clks_for_mx6),
};
static const struct gpmi_devdata gpmi_devdata_imx6ul = {
.type = IS_MX6UL,
.bch_max_ecc_strength = 40,
- .max_chain_delay = 12,
+ .max_chain_delay = 12000,
.clks = gpmi_clks_for_mx6,
.clks_count = ARRAY_SIZE(gpmi_clks_for_mx6),
};
static const struct gpmi_devdata gpmi_devdata_imx6ull = {
.type = IS_MX6ULL,
.bch_max_ecc_strength = 40,
- .max_chain_delay = 12,
+ .max_chain_delay = 12000,
.clks = gpmi_clks_for_mx6,
.clks_count = ARRAY_SIZE(gpmi_clks_for_mx6),
};
+static const char * gpmi_clks_for_mx8qxp[GPMI_CLK_MAX] = {
+ "gpmi_apb", "gpmi_bch", "gpmi_apb_bch",
+};
+
+static const struct gpmi_devdata gpmi_devdata_imx8qxp = {
+ .type = IS_MX8QXP,
+ .bch_max_ecc_strength = 62,
+ .max_chain_delay = 12000,
+ .clks = gpmi_clks_for_mx8qxp,
+ .clks_count = ARRAY_SIZE(gpmi_clks_for_mx8qxp),
+};
+
static irqreturn_t bch_irq(int irq, void *cookie)
{
struct gpmi_nand_data *this = cookie;
r->clock[i] = clk;
}
- if (GPMI_IS_MX6(this))
+ if (GPMI_IS_MX6(this) || GPMI_IS_MX8(this))
/*
* Set the default value for the gpmi clock.
*
/* set chunk0 size if meta size is 0 */
if (!meta) {
- if (GPMI_IS_MX6(this))
+ if (GPMI_IS_MX6(this) || GPMI_IS_MX8(this))
r1_new &= ~MX6Q_BM_BCH_FLASH0LAYOUT0_DATA0_SIZE;
else
r1_new &= ~BM_BCH_FLASH0LAYOUT0_DATA0_SIZE;
* (1) the chip is imx6, and
* (2) the size of the ECC parity is byte aligned.
*/
- if (GPMI_IS_MX6(this) &&
+ if ((GPMI_IS_MX6(this) || GPMI_IS_MX8(this)) &&
((bch_geo->gf_len * bch_geo->ecc_strength) % 8) == 0) {
ecc->read_subpage = gpmi_ecc_read_subpage;
chip->options |= NAND_SUBPAGE_READ;
goto err_out;
chip->dummy_controller.ops = &gpmi_nand_controller_ops;
- ret = nand_scan(mtd, GPMI_IS_MX6(this) ? 2 : 1);
+ ret = nand_scan(mtd, (GPMI_IS_MX6(this) || GPMI_IS_MX8(this)) ? 2 : 1);
if (ret)
goto err_out;
}, {
.compatible = "fsl,imx6ull-gpmi-nand",
.data = &gpmi_devdata_imx6ull,
+ }, {
+ .compatible = "fsl,imx8qxp-gpmi-nand",
+ .data = &gpmi_devdata_imx8qxp,
}, {}
};
MODULE_DEVICE_TABLE(of, gpmi_nand_id_table);
IS_MX7D,
IS_MX6UL,
IS_MX6ULL,
+ IS_MX8QXP,
};
struct gpmi_devdata {
#define GPMI_IS_MX7D(x) ((x)->devdata->type == IS_MX7D)
#define GPMI_IS_MX6UL(x) ((x)->devdata->type == IS_MX6UL)
#define GPMI_IS_MX6ULL(x) ((x)->devdata->type == IS_MX6ULL)
+#define GPMI_IS_MX8QXP(x) ((x)->devdata->type == IS_MX8QXP)
#define GPMI_IS_MX6(x) (GPMI_IS_MX6Q(x) || GPMI_IS_MX6QP(x) || \
GPMI_IS_MX6SX(x) || GPMI_IS_MX6UL(x) || \
GPMI_IS_MX6ULL(x) || GPMI_IS_MX7D(x))
+#define GPMI_IS_MX8(x) (GPMI_IS_MX8QXP(x))
+
#endif