1 /* 2 * NXP GPMI NAND flash driver (DT initialization) 3 * 4 * Copyright (C) 2018 Toradex 5 * Authors: 6 * Stefan Agner <stefan.agner@toradex.com> 7 * 8 * Based on denali_dt.c 9 * 10 * SPDX-License-Identifier: GPL-2.0+ 11 */ 12 13 #include <dm.h> 14 #include <linux/io.h> 15 #include <linux/ioport.h> 16 #include <linux/printk.h> 17 18 #include "mxs_nand.h" 19 20 struct mxs_nand_dt_data { 21 unsigned int max_ecc_strength_supported; 22 }; 23 24 static const struct mxs_nand_dt_data mxs_nand_imx6q_data = { 25 .max_ecc_strength_supported = 40, 26 }; 27 28 static const struct mxs_nand_dt_data mxs_nand_imx7d_data = { 29 .max_ecc_strength_supported = 62, 30 }; 31 32 static const struct udevice_id mxs_nand_dt_ids[] = { 33 { 34 .compatible = "fsl,imx6q-gpmi-nand", 35 .data = (unsigned long)&mxs_nand_imx6q_data, 36 }, 37 { 38 .compatible = "fsl,imx7d-gpmi-nand", 39 .data = (unsigned long)&mxs_nand_imx7d_data, 40 }, 41 { /* sentinel */ } 42 }; 43 44 static int mxs_nand_dt_probe(struct udevice *dev) 45 { 46 struct mxs_nand_info *info = dev_get_priv(dev); 47 const struct mxs_nand_dt_data *data; 48 struct resource res; 49 int ret; 50 51 data = (void *)dev_get_driver_data(dev); 52 if (data) 53 info->max_ecc_strength_supported = data->max_ecc_strength_supported; 54 55 info->dev = dev; 56 57 ret = dev_read_resource_byname(dev, "gpmi-nand", &res); 58 if (ret) 59 return ret; 60 61 info->gpmi_regs = devm_ioremap(dev, res.start, resource_size(&res)); 62 63 64 ret = dev_read_resource_byname(dev, "bch", &res); 65 if (ret) 66 return ret; 67 68 info->bch_regs = devm_ioremap(dev, res.start, resource_size(&res)); 69 70 info->use_minimum_ecc = dev_read_bool(dev, "fsl,use-minimum-ecc"); 71 72 return mxs_nand_init_ctrl(info); 73 } 74 75 U_BOOT_DRIVER(mxs_nand_dt) = { 76 .name = "mxs-nand-dt", 77 .id = UCLASS_MTD, 78 .of_match = mxs_nand_dt_ids, 79 .probe = mxs_nand_dt_probe, 80 .priv_auto_alloc_size = sizeof(struct mxs_nand_info), 81 }; 82 83 void board_nand_init(void) 84 { 85 struct udevice *dev; 86 int ret; 87 88 ret = uclass_get_device_by_driver(UCLASS_MTD, 89 DM_GET_DRIVER(mxs_nand_dt), 90 &dev); 91 if (ret && ret != -ENODEV) 92 pr_err("Failed to initialize MXS NAND controller. (error %d)\n", 93 ret); 94 } 95