1 /* 2 * Copyright 2011 Freescale Semiconductor, Inc 3 * 4 * Freescale Integrated Flash Controller 5 * 6 * Author: Dipen Dudhat <Dipen.Dudhat@freescale.com> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 */ 22 #include <linux/module.h> 23 #include <linux/kernel.h> 24 #include <linux/compiler.h> 25 #include <linux/sched.h> 26 #include <linux/spinlock.h> 27 #include <linux/types.h> 28 #include <linux/slab.h> 29 #include <linux/io.h> 30 #include <linux/of.h> 31 #include <linux/of_device.h> 32 #include <linux/platform_device.h> 33 #include <linux/fsl_ifc.h> 34 #include <asm/prom.h> 35 36 struct fsl_ifc_ctrl *fsl_ifc_ctrl_dev; 37 EXPORT_SYMBOL(fsl_ifc_ctrl_dev); 38 39 /* 40 * convert_ifc_address - convert the base address 41 * @addr_base: base address of the memory bank 42 */ 43 unsigned int convert_ifc_address(phys_addr_t addr_base) 44 { 45 return addr_base & CSPR_BA; 46 } 47 EXPORT_SYMBOL(convert_ifc_address); 48 49 /* 50 * fsl_ifc_find - find IFC bank 51 * @addr_base: base address of the memory bank 52 * 53 * This function walks IFC banks comparing "Base address" field of the CSPR 54 * registers with the supplied addr_base argument. When bases match this 55 * function returns bank number (starting with 0), otherwise it returns 56 * appropriate errno value. 57 */ 58 int fsl_ifc_find(phys_addr_t addr_base) 59 { 60 int i = 0; 61 62 if (!fsl_ifc_ctrl_dev || !fsl_ifc_ctrl_dev->regs) 63 return -ENODEV; 64 65 for (i = 0; i < fsl_ifc_ctrl_dev->banks; i++) { 66 u32 cspr = ifc_in32(&fsl_ifc_ctrl_dev->regs->cspr_cs[i].cspr); 67 if (cspr & CSPR_V && (cspr & CSPR_BA) == 68 convert_ifc_address(addr_base)) 69 return i; 70 } 71 72 return -ENOENT; 73 } 74 EXPORT_SYMBOL(fsl_ifc_find); 75 76 static int fsl_ifc_ctrl_init(struct fsl_ifc_ctrl *ctrl) 77 { 78 struct fsl_ifc_regs __iomem *ifc = ctrl->regs; 79 80 /* 81 * Clear all the common status and event registers 82 */ 83 if (ifc_in32(&ifc->cm_evter_stat) & IFC_CM_EVTER_STAT_CSER) 84 ifc_out32(IFC_CM_EVTER_STAT_CSER, &ifc->cm_evter_stat); 85 86 /* enable all error and events */ 87 ifc_out32(IFC_CM_EVTER_EN_CSEREN, &ifc->cm_evter_en); 88 89 /* enable all error and event interrupts */ 90 ifc_out32(IFC_CM_EVTER_INTR_EN_CSERIREN, &ifc->cm_evter_intr_en); 91 ifc_out32(0x0, &ifc->cm_erattr0); 92 ifc_out32(0x0, &ifc->cm_erattr1); 93 94 return 0; 95 } 96 97 static int fsl_ifc_ctrl_remove(struct platform_device *dev) 98 { 99 struct fsl_ifc_ctrl *ctrl = dev_get_drvdata(&dev->dev); 100 101 free_irq(ctrl->nand_irq, ctrl); 102 free_irq(ctrl->irq, ctrl); 103 104 irq_dispose_mapping(ctrl->nand_irq); 105 irq_dispose_mapping(ctrl->irq); 106 107 iounmap(ctrl->regs); 108 109 dev_set_drvdata(&dev->dev, NULL); 110 kfree(ctrl); 111 112 return 0; 113 } 114 115 /* 116 * NAND events are split between an operational interrupt which only 117 * receives OPC, and an error interrupt that receives everything else, 118 * including non-NAND errors. Whichever interrupt gets to it first 119 * records the status and wakes the wait queue. 120 */ 121 static DEFINE_SPINLOCK(nand_irq_lock); 122 123 static u32 check_nand_stat(struct fsl_ifc_ctrl *ctrl) 124 { 125 struct fsl_ifc_regs __iomem *ifc = ctrl->regs; 126 unsigned long flags; 127 u32 stat; 128 129 spin_lock_irqsave(&nand_irq_lock, flags); 130 131 stat = ifc_in32(&ifc->ifc_nand.nand_evter_stat); 132 if (stat) { 133 ifc_out32(stat, &ifc->ifc_nand.nand_evter_stat); 134 ctrl->nand_stat = stat; 135 wake_up(&ctrl->nand_wait); 136 } 137 138 spin_unlock_irqrestore(&nand_irq_lock, flags); 139 140 return stat; 141 } 142 143 static irqreturn_t fsl_ifc_nand_irq(int irqno, void *data) 144 { 145 struct fsl_ifc_ctrl *ctrl = data; 146 147 if (check_nand_stat(ctrl)) 148 return IRQ_HANDLED; 149 150 return IRQ_NONE; 151 } 152 153 /* 154 * NOTE: This interrupt is used to report ifc events of various kinds, 155 * such as transaction errors on the chipselects. 156 */ 157 static irqreturn_t fsl_ifc_ctrl_irq(int irqno, void *data) 158 { 159 struct fsl_ifc_ctrl *ctrl = data; 160 struct fsl_ifc_regs __iomem *ifc = ctrl->regs; 161 u32 err_axiid, err_srcid, status, cs_err, err_addr; 162 irqreturn_t ret = IRQ_NONE; 163 164 /* read for chip select error */ 165 cs_err = ifc_in32(&ifc->cm_evter_stat); 166 if (cs_err) { 167 dev_err(ctrl->dev, "transaction sent to IFC is not mapped to" 168 "any memory bank 0x%08X\n", cs_err); 169 /* clear the chip select error */ 170 ifc_out32(IFC_CM_EVTER_STAT_CSER, &ifc->cm_evter_stat); 171 172 /* read error attribute registers print the error information */ 173 status = ifc_in32(&ifc->cm_erattr0); 174 err_addr = ifc_in32(&ifc->cm_erattr1); 175 176 if (status & IFC_CM_ERATTR0_ERTYP_READ) 177 dev_err(ctrl->dev, "Read transaction error" 178 "CM_ERATTR0 0x%08X\n", status); 179 else 180 dev_err(ctrl->dev, "Write transaction error" 181 "CM_ERATTR0 0x%08X\n", status); 182 183 err_axiid = (status & IFC_CM_ERATTR0_ERAID) >> 184 IFC_CM_ERATTR0_ERAID_SHIFT; 185 dev_err(ctrl->dev, "AXI ID of the error" 186 "transaction 0x%08X\n", err_axiid); 187 188 err_srcid = (status & IFC_CM_ERATTR0_ESRCID) >> 189 IFC_CM_ERATTR0_ESRCID_SHIFT; 190 dev_err(ctrl->dev, "SRC ID of the error" 191 "transaction 0x%08X\n", err_srcid); 192 193 dev_err(ctrl->dev, "Transaction Address corresponding to error" 194 "ERADDR 0x%08X\n", err_addr); 195 196 ret = IRQ_HANDLED; 197 } 198 199 if (check_nand_stat(ctrl)) 200 ret = IRQ_HANDLED; 201 202 return ret; 203 } 204 205 /* 206 * fsl_ifc_ctrl_probe 207 * 208 * called by device layer when it finds a device matching 209 * one our driver can handled. This code allocates all of 210 * the resources needed for the controller only. The 211 * resources for the NAND banks themselves are allocated 212 * in the chip probe function. 213 */ 214 static int fsl_ifc_ctrl_probe(struct platform_device *dev) 215 { 216 int ret = 0; 217 int version, banks; 218 219 dev_info(&dev->dev, "Freescale Integrated Flash Controller\n"); 220 221 fsl_ifc_ctrl_dev = kzalloc(sizeof(*fsl_ifc_ctrl_dev), GFP_KERNEL); 222 if (!fsl_ifc_ctrl_dev) 223 return -ENOMEM; 224 225 dev_set_drvdata(&dev->dev, fsl_ifc_ctrl_dev); 226 227 /* IOMAP the entire IFC region */ 228 fsl_ifc_ctrl_dev->regs = of_iomap(dev->dev.of_node, 0); 229 if (!fsl_ifc_ctrl_dev->regs) { 230 dev_err(&dev->dev, "failed to get memory region\n"); 231 ret = -ENODEV; 232 goto err; 233 } 234 235 version = ifc_in32(&fsl_ifc_ctrl_dev->regs->ifc_rev) & 236 FSL_IFC_VERSION_MASK; 237 banks = (version == FSL_IFC_VERSION_1_0_0) ? 4 : 8; 238 dev_info(&dev->dev, "IFC version %d.%d, %d banks\n", 239 version >> 24, (version >> 16) & 0xf, banks); 240 241 fsl_ifc_ctrl_dev->version = version; 242 fsl_ifc_ctrl_dev->banks = banks; 243 244 if (of_property_read_bool(dev->dev.of_node, "little-endian")) { 245 fsl_ifc_ctrl_dev->little_endian = true; 246 dev_dbg(&dev->dev, "IFC REGISTERS are LITTLE endian\n"); 247 } else { 248 fsl_ifc_ctrl_dev->little_endian = false; 249 dev_dbg(&dev->dev, "IFC REGISTERS are BIG endian\n"); 250 } 251 252 version = ioread32be(&fsl_ifc_ctrl_dev->regs->ifc_rev) & 253 FSL_IFC_VERSION_MASK; 254 banks = (version == FSL_IFC_VERSION_1_0_0) ? 4 : 8; 255 dev_info(&dev->dev, "IFC version %d.%d, %d banks\n", 256 version >> 24, (version >> 16) & 0xf, banks); 257 258 fsl_ifc_ctrl_dev->version = version; 259 fsl_ifc_ctrl_dev->banks = banks; 260 261 /* get the Controller level irq */ 262 fsl_ifc_ctrl_dev->irq = irq_of_parse_and_map(dev->dev.of_node, 0); 263 if (fsl_ifc_ctrl_dev->irq == NO_IRQ) { 264 dev_err(&dev->dev, "failed to get irq resource " 265 "for IFC\n"); 266 ret = -ENODEV; 267 goto err; 268 } 269 270 /* get the nand machine irq */ 271 fsl_ifc_ctrl_dev->nand_irq = 272 irq_of_parse_and_map(dev->dev.of_node, 1); 273 274 fsl_ifc_ctrl_dev->dev = &dev->dev; 275 276 ret = fsl_ifc_ctrl_init(fsl_ifc_ctrl_dev); 277 if (ret < 0) 278 goto err; 279 280 init_waitqueue_head(&fsl_ifc_ctrl_dev->nand_wait); 281 282 ret = request_irq(fsl_ifc_ctrl_dev->irq, fsl_ifc_ctrl_irq, IRQF_SHARED, 283 "fsl-ifc", fsl_ifc_ctrl_dev); 284 if (ret != 0) { 285 dev_err(&dev->dev, "failed to install irq (%d)\n", 286 fsl_ifc_ctrl_dev->irq); 287 goto err_irq; 288 } 289 290 if (fsl_ifc_ctrl_dev->nand_irq) { 291 ret = request_irq(fsl_ifc_ctrl_dev->nand_irq, fsl_ifc_nand_irq, 292 0, "fsl-ifc-nand", fsl_ifc_ctrl_dev); 293 if (ret != 0) { 294 dev_err(&dev->dev, "failed to install irq (%d)\n", 295 fsl_ifc_ctrl_dev->nand_irq); 296 goto err_nandirq; 297 } 298 } 299 300 return 0; 301 302 err_nandirq: 303 free_irq(fsl_ifc_ctrl_dev->nand_irq, fsl_ifc_ctrl_dev); 304 irq_dispose_mapping(fsl_ifc_ctrl_dev->nand_irq); 305 err_irq: 306 free_irq(fsl_ifc_ctrl_dev->irq, fsl_ifc_ctrl_dev); 307 irq_dispose_mapping(fsl_ifc_ctrl_dev->irq); 308 err: 309 return ret; 310 } 311 312 static const struct of_device_id fsl_ifc_match[] = { 313 { 314 .compatible = "fsl,ifc", 315 }, 316 {}, 317 }; 318 319 static struct platform_driver fsl_ifc_ctrl_driver = { 320 .driver = { 321 .name = "fsl-ifc", 322 .of_match_table = fsl_ifc_match, 323 }, 324 .probe = fsl_ifc_ctrl_probe, 325 .remove = fsl_ifc_ctrl_remove, 326 }; 327 328 static int __init fsl_ifc_init(void) 329 { 330 return platform_driver_register(&fsl_ifc_ctrl_driver); 331 } 332 subsys_initcall(fsl_ifc_init); 333 334 MODULE_LICENSE("GPL"); 335 MODULE_AUTHOR("Freescale Semiconductor"); 336 MODULE_DESCRIPTION("Freescale Integrated Flash Controller driver"); 337