diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c index dd1df605a1d61ec8a43ffb5515ea50ce2f3c9b69..ec4db2a359e5de9d7e6a57fb855698115e9722f1 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c @@ -861,7 +861,7 @@ static void gpmi_compute_edo_timing(struct gpmi_nand_data *this, struct resources *r = &this->resources; unsigned long rate = clk_get_rate(r->clock[0]); int mode = this->timing_mode; - int dll_threshold = 16; /* in ns */ + int dll_threshold = this->devdata->max_chain_delay; unsigned long delay; unsigned long clk_period; int t_rea; @@ -886,9 +886,6 @@ static void gpmi_compute_edo_timing(struct gpmi_nand_data *this, /* [3] for GPMI_HW_GPMI_CTRL1 */ hw->wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY; - if (GPMI_IS_MX6Q(this)) - dll_threshold = 12; - /* * Enlarge 10 times for the numerator and denominator in {3}. * This make us to get more accurate result. diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index bb77f750e75a3b1cfee16e5ecbf95efea95ead1a..e88d64e1e9632df9e349616af77d204e2f4e4ca3 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -53,6 +53,24 @@ static struct nand_ecclayout gpmi_hw_ecclayout = { .oobfree = { {.offset = 0, .length = 0} } }; +static const struct gpmi_devdata gpmi_devdata_imx23 = { + .type = IS_MX23, + .bch_max_ecc_strength = 20, + .max_chain_delay = 16, +}; + +static const struct gpmi_devdata gpmi_devdata_imx28 = { + .type = IS_MX28, + .bch_max_ecc_strength = 20, + .max_chain_delay = 16, +}; + +static const struct gpmi_devdata gpmi_devdata_imx6q = { + .type = IS_MX6Q, + .bch_max_ecc_strength = 40, + .max_chain_delay = 12, +}; + static irqreturn_t bch_irq(int irq, void *cookie) { struct gpmi_nand_data *this = cookie; @@ -102,14 +120,8 @@ static inline bool gpmi_check_ecc(struct gpmi_nand_data *this) /* The mx23/mx28 only support the GF13. */ if (geo->gf_len == 14) return false; - - if (geo->ecc_strength > MXS_ECC_STRENGTH_MAX) - return false; - } else if (GPMI_IS_MX6Q(this)) { - if (geo->ecc_strength > MX6_ECC_STRENGTH_MAX) - return false; } - return true; + return geo->ecc_strength <= this->devdata->bch_max_ecc_strength; } /* @@ -270,8 +282,7 @@ static int legacy_set_geometry(struct gpmi_nand_data *this) "We can not support this nand chip." " Its required ecc strength(%d) is beyond our" " capability(%d).\n", geo->ecc_strength, - (GPMI_IS_MX6Q(this) ? MX6_ECC_STRENGTH_MAX - : MXS_ECC_STRENGTH_MAX)); + this->devdata->bch_max_ecc_strength); return -EINVAL; } @@ -1740,23 +1751,16 @@ static int gpmi_nand_init(struct gpmi_nand_data *this) return ret; } -static const struct platform_device_id gpmi_ids[] = { - { .name = "imx23-gpmi-nand", .driver_data = IS_MX23, }, - { .name = "imx28-gpmi-nand", .driver_data = IS_MX28, }, - { .name = "imx6q-gpmi-nand", .driver_data = IS_MX6Q, }, - {} -}; - static const struct of_device_id gpmi_nand_id_table[] = { { .compatible = "fsl,imx23-gpmi-nand", - .data = (void *)&gpmi_ids[IS_MX23], + .data = (void *)&gpmi_devdata_imx23, }, { .compatible = "fsl,imx28-gpmi-nand", - .data = (void *)&gpmi_ids[IS_MX28], + .data = (void *)&gpmi_devdata_imx28, }, { .compatible = "fsl,imx6q-gpmi-nand", - .data = (void *)&gpmi_ids[IS_MX6Q], + .data = (void *)&gpmi_devdata_imx6q, }, {} }; MODULE_DEVICE_TABLE(of, gpmi_nand_id_table); @@ -1767,18 +1771,18 @@ static int gpmi_nand_probe(struct platform_device *pdev) const struct of_device_id *of_id; int ret; + this = devm_kzalloc(&pdev->dev, sizeof(*this), GFP_KERNEL); + if (!this) + return -ENOMEM; + of_id = of_match_device(gpmi_nand_id_table, &pdev->dev); if (of_id) { - pdev->id_entry = of_id->data; + this->devdata = of_id->data; } else { dev_err(&pdev->dev, "Failed to find the right device id.\n"); return -ENODEV; } - this = devm_kzalloc(&pdev->dev, sizeof(*this), GFP_KERNEL); - if (!this) - return -ENOMEM; - platform_set_drvdata(pdev, this); this->pdev = pdev; this->dev = &pdev->dev; @@ -1823,7 +1827,6 @@ static struct platform_driver gpmi_nand_driver = { }, .probe = gpmi_nand_probe, .remove = gpmi_nand_remove, - .id_table = gpmi_ids, }; module_platform_driver(gpmi_nand_driver); diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h index 4c801fa1872530e681e801d2adaee333d4acffb4..7904e8329b67c04829a771a6bef5baf093cf65d9 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h @@ -119,11 +119,24 @@ struct nand_timing { int8_t tRHOH_in_ns; }; +enum gpmi_type { + IS_MX23, + IS_MX28, + IS_MX6Q +}; + +struct gpmi_devdata { + enum gpmi_type type; + int bch_max_ecc_strength; + int max_chain_delay; /* See the async EDO mode */ +}; + struct gpmi_nand_data { /* flags */ #define GPMI_ASYNC_EDO_ENABLED (1 << 0) #define GPMI_TIMING_INIT_OK (1 << 1) int flags; + const struct gpmi_devdata *devdata; /* System Interface */ struct device *dev; @@ -281,15 +294,8 @@ extern int gpmi_read_page(struct gpmi_nand_data *, #define STATUS_ERASED 0xff #define STATUS_UNCORRECTABLE 0xfe -/* BCH's bit correction capability. */ -#define MXS_ECC_STRENGTH_MAX 20 /* mx23 and mx28 */ -#define MX6_ECC_STRENGTH_MAX 40 - -/* Use the platform_id to distinguish different Archs. */ -#define IS_MX23 0x0 -#define IS_MX28 0x1 -#define IS_MX6Q 0x2 -#define GPMI_IS_MX23(x) ((x)->pdev->id_entry->driver_data == IS_MX23) -#define GPMI_IS_MX28(x) ((x)->pdev->id_entry->driver_data == IS_MX28) -#define GPMI_IS_MX6Q(x) ((x)->pdev->id_entry->driver_data == IS_MX6Q) +/* Use the devdata to distinguish different Archs. */ +#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) #endif