1/* 2 * NXP GPMI NAND flash driver (DT initialization) 3 * 4 * Copyright (C) 2018 Toradex 5 * Copyright 2019 NXP 6 * 7 * Authors: 8 * Stefan Agner <stefan.agner@toradex.com> 9 * 10 * Based on denali_dt.c 11 * 12 * SPDX-License-Identifier: GPL-2.0+ 13 */ 14 15#include <dm.h> 16#include <linux/io.h> 17#include <linux/ioport.h> 18#include <linux/printk.h> 19#include <clk.h> 20 21#include <mxs_nand.h> 22 23struct mxs_nand_dt_data { 24 unsigned int max_ecc_strength_supported; 25 int max_chain_delay; /* See the async EDO mode */ 26}; 27 28static const struct mxs_nand_dt_data mxs_nand_imx6q_data = { 29 .max_ecc_strength_supported = 40, 30 .max_chain_delay = 12000, 31}; 32 33static const struct mxs_nand_dt_data mxs_nand_imx6sx_data = { 34 .max_ecc_strength_supported = 62, 35 .max_chain_delay = 12000, 36}; 37 38static const struct mxs_nand_dt_data mxs_nand_imx7d_data = { 39 .max_ecc_strength_supported = 62, 40 .max_chain_delay = 12000, 41}; 42 43static const struct mxs_nand_dt_data mxs_nand_imx8qxp_data = { 44 .max_ecc_strength_supported = 62, 45 .max_chain_delay = 12000, 46}; 47 48static const struct udevice_id mxs_nand_dt_ids[] = { 49 { 50 .compatible = "fsl,imx6q-gpmi-nand", 51 .data = (unsigned long)&mxs_nand_imx6q_data, 52 }, 53 { 54 .compatible = "fsl,imx6qp-gpmi-nand", 55 .data = (unsigned long)&mxs_nand_imx6q_data, 56 }, 57 { 58 .compatible = "fsl,imx6sx-gpmi-nand", 59 .data = (unsigned long)&mxs_nand_imx6sx_data, 60 }, 61 { 62 .compatible = "fsl,imx7d-gpmi-nand", 63 .data = (unsigned long)&mxs_nand_imx7d_data, 64 }, 65 { 66 .compatible = "fsl,imx8qxp-gpmi-nand", 67 .data = (unsigned long)&mxs_nand_imx8qxp_data, 68 }, 69 { /* sentinel */ } 70}; 71 72static int mxs_nand_dt_probe(struct udevice *dev) 73{ 74 struct mxs_nand_info *info = dev_get_priv(dev); 75 const struct mxs_nand_dt_data *data; 76 struct resource res; 77 int ret; 78 79 data = (void *)dev_get_driver_data(dev); 80 if (data) { 81 info->max_ecc_strength_supported = data->max_ecc_strength_supported; 82 info->max_chain_delay = data->max_chain_delay; 83 } 84 85 info->dev = dev; 86 87 ret = dev_read_resource_byname(dev, "gpmi-nand", &res); 88 if (ret) 89 return ret; 90 91 info->gpmi_regs = devm_ioremap(dev, res.start, resource_size(&res)); 92 93 94 ret = dev_read_resource_byname(dev, "bch", &res); 95 if (ret) 96 return ret; 97 98 info->bch_regs = devm_ioremap(dev, res.start, resource_size(&res)); 99 100 info->use_minimum_ecc = dev_read_bool(dev, "fsl,use-minimum-ecc"); 101 102 if (IS_ENABLED(CONFIG_CLK) && 103 (IS_ENABLED(CONFIG_IMX8) || IS_ENABLED(CONFIG_IMX8M))) { 104 /* Assigned clock already set clock */ 105 struct clk gpmi_clk; 106 107 info->gpmi_clk = devm_clk_get(dev, "gpmi_io"); 108 109 if (IS_ERR(info->gpmi_clk)) { 110 ret = PTR_ERR(info->gpmi_clk); 111 debug("Can't get gpmi io clk: %d\n", ret); 112 return ret; 113 } 114 115 ret = clk_enable(info->gpmi_clk); 116 if (ret < 0) { 117 debug("Can't enable gpmi io clk: %d\n", ret); 118 return ret; 119 } 120 121 if (IS_ENABLED(CONFIG_IMX8)) { 122 ret = clk_get_by_name(dev, "gpmi_apb", &gpmi_clk); 123 if (ret < 0) { 124 debug("Can't get gpmi_apb clk: %d\n", ret); 125 return ret; 126 } 127 128 ret = clk_enable(&gpmi_clk); 129 if (ret < 0) { 130 debug("Can't enable gpmi_apb clk: %d\n", ret); 131 return ret; 132 } 133 134 ret = clk_get_by_name(dev, "gpmi_bch", &gpmi_clk); 135 if (ret < 0) { 136 debug("Can't get gpmi_bch clk: %d\n", ret); 137 return ret; 138 } 139 140 ret = clk_enable(&gpmi_clk); 141 if (ret < 0) { 142 debug("Can't enable gpmi_bch clk: %d\n", ret); 143 return ret; 144 } 145 } 146 147 ret = clk_get_by_name(dev, "gpmi_bch_apb", &gpmi_clk); 148 if (ret < 0) { 149 debug("Can't get gpmi_bch_apb clk: %d\n", ret); 150 return ret; 151 } 152 153 ret = clk_enable(&gpmi_clk); 154 if (ret < 0) { 155 debug("Can't enable gpmi_bch_apb clk: %d\n", ret); 156 return ret; 157 } 158 } 159 160 return mxs_nand_init_ctrl(info); 161} 162 163U_BOOT_DRIVER(mxs_nand_dt) = { 164 .name = "mxs-nand-dt", 165 .id = UCLASS_MTD, 166 .of_match = mxs_nand_dt_ids, 167 .probe = mxs_nand_dt_probe, 168 .priv_auto = sizeof(struct mxs_nand_info), 169}; 170 171void board_nand_init(void) 172{ 173 struct udevice *dev; 174 int ret; 175 176 ret = uclass_get_device_by_driver(UCLASS_MTD, 177 DM_DRIVER_GET(mxs_nand_dt), 178 &dev); 179 if (ret && ret != -ENODEV) 180 pr_err("Failed to initialize MXS NAND controller. (error %d)\n", 181 ret); 182} 183