1 /* 2 * Freescale LBC and UPM routines. 3 * 4 * Copyright © 2007-2008 MontaVista Software, Inc. 5 * Copyright © 2010 Freescale Semiconductor 6 * 7 * Author: Anton Vorontsov <avorontsov@ru.mvista.com> 8 * Author: Jack Lan <Jack.Lan@freescale.com> 9 * Author: Roy Zang <tie-fei.zang@freescale.com> 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 */ 16 17 #include <linux/init.h> 18 #include <linux/module.h> 19 #include <linux/kernel.h> 20 #include <linux/compiler.h> 21 #include <linux/spinlock.h> 22 #include <linux/types.h> 23 #include <linux/io.h> 24 #include <linux/of.h> 25 #include <linux/slab.h> 26 #include <linux/platform_device.h> 27 #include <linux/interrupt.h> 28 #include <linux/mod_devicetable.h> 29 #include <asm/prom.h> 30 #include <asm/fsl_lbc.h> 31 32 static spinlock_t fsl_lbc_lock = __SPIN_LOCK_UNLOCKED(fsl_lbc_lock); 33 struct fsl_lbc_ctrl *fsl_lbc_ctrl_dev; 34 EXPORT_SYMBOL(fsl_lbc_ctrl_dev); 35 36 /** 37 * fsl_lbc_addr - convert the base address 38 * @addr_base: base address of the memory bank 39 * 40 * This function converts a base address of lbc into the right format for the 41 * BR register. If the SOC has eLBC then it returns 32bit physical address 42 * else it convers a 34bit local bus physical address to correct format of 43 * 32bit address for BR register (Example: MPC8641). 44 */ 45 u32 fsl_lbc_addr(phys_addr_t addr_base) 46 { 47 struct device_node *np = fsl_lbc_ctrl_dev->dev->of_node; 48 u32 addr = addr_base & 0xffff8000; 49 50 if (of_device_is_compatible(np, "fsl,elbc")) 51 return addr; 52 53 return addr | ((addr_base & 0x300000000ull) >> 19); 54 } 55 EXPORT_SYMBOL(fsl_lbc_addr); 56 57 /** 58 * fsl_lbc_find - find Localbus bank 59 * @addr_base: base address of the memory bank 60 * 61 * This function walks LBC banks comparing "Base address" field of the BR 62 * registers with the supplied addr_base argument. When bases match this 63 * function returns bank number (starting with 0), otherwise it returns 64 * appropriate errno value. 65 */ 66 int fsl_lbc_find(phys_addr_t addr_base) 67 { 68 int i; 69 struct fsl_lbc_regs __iomem *lbc; 70 71 if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs) 72 return -ENODEV; 73 74 lbc = fsl_lbc_ctrl_dev->regs; 75 for (i = 0; i < ARRAY_SIZE(lbc->bank); i++) { 76 __be32 br = in_be32(&lbc->bank[i].br); 77 __be32 or = in_be32(&lbc->bank[i].or); 78 79 if (br & BR_V && (br & or & BR_BA) == fsl_lbc_addr(addr_base)) 80 return i; 81 } 82 83 return -ENOENT; 84 } 85 EXPORT_SYMBOL(fsl_lbc_find); 86 87 /** 88 * fsl_upm_find - find pre-programmed UPM via base address 89 * @addr_base: base address of the memory bank controlled by the UPM 90 * @upm: pointer to the allocated fsl_upm structure 91 * 92 * This function fills fsl_upm structure so you can use it with the rest of 93 * UPM API. On success this function returns 0, otherwise it returns 94 * appropriate errno value. 95 */ 96 int fsl_upm_find(phys_addr_t addr_base, struct fsl_upm *upm) 97 { 98 int bank; 99 __be32 br; 100 struct fsl_lbc_regs __iomem *lbc; 101 102 bank = fsl_lbc_find(addr_base); 103 if (bank < 0) 104 return bank; 105 106 if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs) 107 return -ENODEV; 108 109 lbc = fsl_lbc_ctrl_dev->regs; 110 br = in_be32(&lbc->bank[bank].br); 111 112 switch (br & BR_MSEL) { 113 case BR_MS_UPMA: 114 upm->mxmr = &lbc->mamr; 115 break; 116 case BR_MS_UPMB: 117 upm->mxmr = &lbc->mbmr; 118 break; 119 case BR_MS_UPMC: 120 upm->mxmr = &lbc->mcmr; 121 break; 122 default: 123 return -EINVAL; 124 } 125 126 switch (br & BR_PS) { 127 case BR_PS_8: 128 upm->width = 8; 129 break; 130 case BR_PS_16: 131 upm->width = 16; 132 break; 133 case BR_PS_32: 134 upm->width = 32; 135 break; 136 default: 137 return -EINVAL; 138 } 139 140 return 0; 141 } 142 EXPORT_SYMBOL(fsl_upm_find); 143 144 /** 145 * fsl_upm_run_pattern - actually run an UPM pattern 146 * @upm: pointer to the fsl_upm structure obtained via fsl_upm_find 147 * @io_base: remapped pointer to where memory access should happen 148 * @mar: MAR register content during pattern execution 149 * 150 * This function triggers dummy write to the memory specified by the io_base, 151 * thus UPM pattern actually executed. Note that mar usage depends on the 152 * pre-programmed AMX bits in the UPM RAM. 153 */ 154 int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base, u32 mar) 155 { 156 int ret = 0; 157 unsigned long flags; 158 159 if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs) 160 return -ENODEV; 161 162 spin_lock_irqsave(&fsl_lbc_lock, flags); 163 164 out_be32(&fsl_lbc_ctrl_dev->regs->mar, mar); 165 166 switch (upm->width) { 167 case 8: 168 out_8(io_base, 0x0); 169 break; 170 case 16: 171 out_be16(io_base, 0x0); 172 break; 173 case 32: 174 out_be32(io_base, 0x0); 175 break; 176 default: 177 ret = -EINVAL; 178 break; 179 } 180 181 spin_unlock_irqrestore(&fsl_lbc_lock, flags); 182 183 return ret; 184 } 185 EXPORT_SYMBOL(fsl_upm_run_pattern); 186 187 static int __devinit fsl_lbc_ctrl_init(struct fsl_lbc_ctrl *ctrl) 188 { 189 struct fsl_lbc_regs __iomem *lbc = ctrl->regs; 190 191 /* clear event registers */ 192 setbits32(&lbc->ltesr, LTESR_CLEAR); 193 out_be32(&lbc->lteatr, 0); 194 out_be32(&lbc->ltear, 0); 195 out_be32(&lbc->lteccr, LTECCR_CLEAR); 196 out_be32(&lbc->ltedr, LTEDR_ENABLE); 197 198 /* Enable interrupts for any detected events */ 199 out_be32(&lbc->lteir, LTEIR_ENABLE); 200 201 return 0; 202 } 203 204 /* 205 * NOTE: This interrupt is used to report localbus events of various kinds, 206 * such as transaction errors on the chipselects. 207 */ 208 209 static irqreturn_t fsl_lbc_ctrl_irq(int irqno, void *data) 210 { 211 struct fsl_lbc_ctrl *ctrl = data; 212 struct fsl_lbc_regs __iomem *lbc = ctrl->regs; 213 u32 status; 214 215 status = in_be32(&lbc->ltesr); 216 if (!status) 217 return IRQ_NONE; 218 219 out_be32(&lbc->ltesr, LTESR_CLEAR); 220 out_be32(&lbc->lteatr, 0); 221 out_be32(&lbc->ltear, 0); 222 ctrl->irq_status = status; 223 224 if (status & LTESR_BM) 225 dev_err(ctrl->dev, "Local bus monitor time-out: " 226 "LTESR 0x%08X\n", status); 227 if (status & LTESR_WP) 228 dev_err(ctrl->dev, "Write protect error: " 229 "LTESR 0x%08X\n", status); 230 if (status & LTESR_ATMW) 231 dev_err(ctrl->dev, "Atomic write error: " 232 "LTESR 0x%08X\n", status); 233 if (status & LTESR_ATMR) 234 dev_err(ctrl->dev, "Atomic read error: " 235 "LTESR 0x%08X\n", status); 236 if (status & LTESR_CS) 237 dev_err(ctrl->dev, "Chip select error: " 238 "LTESR 0x%08X\n", status); 239 if (status & LTESR_UPM) 240 ; 241 if (status & LTESR_FCT) { 242 dev_err(ctrl->dev, "FCM command time-out: " 243 "LTESR 0x%08X\n", status); 244 smp_wmb(); 245 wake_up(&ctrl->irq_wait); 246 } 247 if (status & LTESR_PAR) { 248 dev_err(ctrl->dev, "Parity or Uncorrectable ECC error: " 249 "LTESR 0x%08X\n", status); 250 smp_wmb(); 251 wake_up(&ctrl->irq_wait); 252 } 253 if (status & LTESR_CC) { 254 smp_wmb(); 255 wake_up(&ctrl->irq_wait); 256 } 257 if (status & ~LTESR_MASK) 258 dev_err(ctrl->dev, "Unknown error: " 259 "LTESR 0x%08X\n", status); 260 return IRQ_HANDLED; 261 } 262 263 /* 264 * fsl_lbc_ctrl_probe 265 * 266 * called by device layer when it finds a device matching 267 * one our driver can handled. This code allocates all of 268 * the resources needed for the controller only. The 269 * resources for the NAND banks themselves are allocated 270 * in the chip probe function. 271 */ 272 273 static int __devinit fsl_lbc_ctrl_probe(struct platform_device *dev) 274 { 275 int ret; 276 277 if (!dev->dev.of_node) { 278 dev_err(&dev->dev, "Device OF-Node is NULL"); 279 return -EFAULT; 280 } 281 282 fsl_lbc_ctrl_dev = kzalloc(sizeof(*fsl_lbc_ctrl_dev), GFP_KERNEL); 283 if (!fsl_lbc_ctrl_dev) 284 return -ENOMEM; 285 286 dev_set_drvdata(&dev->dev, fsl_lbc_ctrl_dev); 287 288 spin_lock_init(&fsl_lbc_ctrl_dev->lock); 289 init_waitqueue_head(&fsl_lbc_ctrl_dev->irq_wait); 290 291 fsl_lbc_ctrl_dev->regs = of_iomap(dev->dev.of_node, 0); 292 if (!fsl_lbc_ctrl_dev->regs) { 293 dev_err(&dev->dev, "failed to get memory region\n"); 294 ret = -ENODEV; 295 goto err; 296 } 297 298 fsl_lbc_ctrl_dev->irq = irq_of_parse_and_map(dev->dev.of_node, 0); 299 if (fsl_lbc_ctrl_dev->irq == NO_IRQ) { 300 dev_err(&dev->dev, "failed to get irq resource\n"); 301 ret = -ENODEV; 302 goto err; 303 } 304 305 fsl_lbc_ctrl_dev->dev = &dev->dev; 306 307 ret = fsl_lbc_ctrl_init(fsl_lbc_ctrl_dev); 308 if (ret < 0) 309 goto err; 310 311 ret = request_irq(fsl_lbc_ctrl_dev->irq, fsl_lbc_ctrl_irq, 0, 312 "fsl-lbc", fsl_lbc_ctrl_dev); 313 if (ret != 0) { 314 dev_err(&dev->dev, "failed to install irq (%d)\n", 315 fsl_lbc_ctrl_dev->irq); 316 ret = fsl_lbc_ctrl_dev->irq; 317 goto err; 318 } 319 320 return 0; 321 322 err: 323 iounmap(fsl_lbc_ctrl_dev->regs); 324 kfree(fsl_lbc_ctrl_dev); 325 return ret; 326 } 327 328 static const struct of_device_id fsl_lbc_match[] = { 329 { .compatible = "fsl,elbc", }, 330 { .compatible = "fsl,pq3-localbus", }, 331 { .compatible = "fsl,pq2-localbus", }, 332 { .compatible = "fsl,pq2pro-localbus", }, 333 {}, 334 }; 335 336 static struct platform_driver fsl_lbc_ctrl_driver = { 337 .driver = { 338 .name = "fsl-lbc", 339 .of_match_table = fsl_lbc_match, 340 }, 341 .probe = fsl_lbc_ctrl_probe, 342 }; 343 344 static int __init fsl_lbc_init(void) 345 { 346 return platform_driver_register(&fsl_lbc_ctrl_driver); 347 } 348 module_init(fsl_lbc_init); 349