1103 lines · c
1/*2 * SMI (Serial Memory Controller) device driver for Serial NOR Flash on3 * SPEAr platform4 * The serial nor interface is largely based on m25p80.c, however the SPI5 * interface has been replaced by SMI.6 *7 * Copyright © 2010 STMicroelectronics.8 * Ashish Priyadarshi9 * Shiraz Hashim <shiraz.linux.kernel@gmail.com>10 *11 * This file is licensed under the terms of the GNU General Public12 * License version 2. This program is licensed "as is" without any13 * warranty of any kind, whether express or implied.14 */15 16#include <linux/clk.h>17#include <linux/delay.h>18#include <linux/device.h>19#include <linux/err.h>20#include <linux/errno.h>21#include <linux/interrupt.h>22#include <linux/io.h>23#include <linux/ioport.h>24#include <linux/jiffies.h>25#include <linux/kernel.h>26#include <linux/module.h>27#include <linux/param.h>28#include <linux/platform_device.h>29#include <linux/pm.h>30#include <linux/mtd/mtd.h>31#include <linux/mtd/partitions.h>32#include <linux/mtd/spear_smi.h>33#include <linux/mutex.h>34#include <linux/sched.h>35#include <linux/slab.h>36#include <linux/wait.h>37#include <linux/of.h>38#include <linux/of_address.h>39 40/* SMI clock rate */41#define SMI_MAX_CLOCK_FREQ 50000000 /* 50 MHz */42 43/* MAX time out to safely come out of a erase or write busy conditions */44#define SMI_PROBE_TIMEOUT (HZ / 10)45#define SMI_MAX_TIME_OUT (3 * HZ)46 47/* timeout for command completion */48#define SMI_CMD_TIMEOUT (HZ / 10)49 50/* registers of smi */51#define SMI_CR1 0x0 /* SMI control register 1 */52#define SMI_CR2 0x4 /* SMI control register 2 */53#define SMI_SR 0x8 /* SMI status register */54#define SMI_TR 0xC /* SMI transmit register */55#define SMI_RR 0x10 /* SMI receive register */56 57/* defines for control_reg 1 */58#define BANK_EN (0xF << 0) /* enables all banks */59#define DSEL_TIME (0x6 << 4) /* Deselect time 6 + 1 SMI_CK periods */60#define SW_MODE (0x1 << 28) /* enables SW Mode */61#define WB_MODE (0x1 << 29) /* Write Burst Mode */62#define FAST_MODE (0x1 << 15) /* Fast Mode */63#define HOLD1 (0x1 << 16) /* Clock Hold period selection */64 65/* defines for control_reg 2 */66#define SEND (0x1 << 7) /* Send data */67#define TFIE (0x1 << 8) /* Transmission Flag Interrupt Enable */68#define WCIE (0x1 << 9) /* Write Complete Interrupt Enable */69#define RD_STATUS_REG (0x1 << 10) /* reads status reg */70#define WE (0x1 << 11) /* Write Enable */71 72#define TX_LEN_SHIFT 073#define RX_LEN_SHIFT 474#define BANK_SHIFT 1275 76/* defines for status register */77#define SR_WIP 0x1 /* Write in progress */78#define SR_WEL 0x2 /* Write enable latch */79#define SR_BP0 0x4 /* Block protect 0 */80#define SR_BP1 0x8 /* Block protect 1 */81#define SR_BP2 0x10 /* Block protect 2 */82#define SR_SRWD 0x80 /* SR write protect */83#define TFF 0x100 /* Transfer Finished Flag */84#define WCF 0x200 /* Transfer Finished Flag */85#define ERF1 0x400 /* Forbidden Write Request */86#define ERF2 0x800 /* Forbidden Access */87 88#define WM_SHIFT 1289 90/* flash opcodes */91#define OPCODE_RDID 0x9f /* Read JEDEC ID */92 93/* Flash Device Ids maintenance section */94 95/* data structure to maintain flash ids from different vendors */96struct flash_device {97 char *name;98 u8 erase_cmd;99 u32 device_id;100 u32 pagesize;101 unsigned long sectorsize;102 unsigned long size_in_bytes;103};104 105#define FLASH_ID(n, es, id, psize, ssize, size) \106{ \107 .name = n, \108 .erase_cmd = es, \109 .device_id = id, \110 .pagesize = psize, \111 .sectorsize = ssize, \112 .size_in_bytes = size \113}114 115static struct flash_device flash_devices[] = {116 FLASH_ID("st m25p16" , 0xd8, 0x00152020, 0x100, 0x10000, 0x200000),117 FLASH_ID("st m25p32" , 0xd8, 0x00162020, 0x100, 0x10000, 0x400000),118 FLASH_ID("st m25p64" , 0xd8, 0x00172020, 0x100, 0x10000, 0x800000),119 FLASH_ID("st m25p128" , 0xd8, 0x00182020, 0x100, 0x40000, 0x1000000),120 FLASH_ID("st m25p05" , 0xd8, 0x00102020, 0x80 , 0x8000 , 0x10000),121 FLASH_ID("st m25p10" , 0xd8, 0x00112020, 0x80 , 0x8000 , 0x20000),122 FLASH_ID("st m25p20" , 0xd8, 0x00122020, 0x100, 0x10000, 0x40000),123 FLASH_ID("st m25p40" , 0xd8, 0x00132020, 0x100, 0x10000, 0x80000),124 FLASH_ID("st m25p80" , 0xd8, 0x00142020, 0x100, 0x10000, 0x100000),125 FLASH_ID("st m45pe10" , 0xd8, 0x00114020, 0x100, 0x10000, 0x20000),126 FLASH_ID("st m45pe20" , 0xd8, 0x00124020, 0x100, 0x10000, 0x40000),127 FLASH_ID("st m45pe40" , 0xd8, 0x00134020, 0x100, 0x10000, 0x80000),128 FLASH_ID("st m45pe80" , 0xd8, 0x00144020, 0x100, 0x10000, 0x100000),129 FLASH_ID("sp s25fl004" , 0xd8, 0x00120201, 0x100, 0x10000, 0x80000),130 FLASH_ID("sp s25fl008" , 0xd8, 0x00130201, 0x100, 0x10000, 0x100000),131 FLASH_ID("sp s25fl016" , 0xd8, 0x00140201, 0x100, 0x10000, 0x200000),132 FLASH_ID("sp s25fl032" , 0xd8, 0x00150201, 0x100, 0x10000, 0x400000),133 FLASH_ID("sp s25fl064" , 0xd8, 0x00160201, 0x100, 0x10000, 0x800000),134 FLASH_ID("atmel 25f512" , 0x52, 0x0065001F, 0x80 , 0x8000 , 0x10000),135 FLASH_ID("atmel 25f1024" , 0x52, 0x0060001F, 0x100, 0x8000 , 0x20000),136 FLASH_ID("atmel 25f2048" , 0x52, 0x0063001F, 0x100, 0x10000, 0x40000),137 FLASH_ID("atmel 25f4096" , 0x52, 0x0064001F, 0x100, 0x10000, 0x80000),138 FLASH_ID("atmel 25fs040" , 0xd7, 0x0004661F, 0x100, 0x10000, 0x80000),139 FLASH_ID("mac 25l512" , 0xd8, 0x001020C2, 0x010, 0x10000, 0x10000),140 FLASH_ID("mac 25l1005" , 0xd8, 0x001120C2, 0x010, 0x10000, 0x20000),141 FLASH_ID("mac 25l2005" , 0xd8, 0x001220C2, 0x010, 0x10000, 0x40000),142 FLASH_ID("mac 25l4005" , 0xd8, 0x001320C2, 0x010, 0x10000, 0x80000),143 FLASH_ID("mac 25l4005a" , 0xd8, 0x001320C2, 0x010, 0x10000, 0x80000),144 FLASH_ID("mac 25l8005" , 0xd8, 0x001420C2, 0x010, 0x10000, 0x100000),145 FLASH_ID("mac 25l1605" , 0xd8, 0x001520C2, 0x100, 0x10000, 0x200000),146 FLASH_ID("mac 25l1605a" , 0xd8, 0x001520C2, 0x010, 0x10000, 0x200000),147 FLASH_ID("mac 25l3205" , 0xd8, 0x001620C2, 0x100, 0x10000, 0x400000),148 FLASH_ID("mac 25l3205a" , 0xd8, 0x001620C2, 0x100, 0x10000, 0x400000),149 FLASH_ID("mac 25l6405" , 0xd8, 0x001720C2, 0x100, 0x10000, 0x800000),150};151 152/* Define spear specific structures */153 154struct spear_snor_flash;155 156/**157 * struct spear_smi - Structure for SMI Device158 *159 * @clk: functional clock160 * @status: current status register of SMI.161 * @clk_rate: functional clock rate of SMI (default: SMI_MAX_CLOCK_FREQ)162 * @lock: lock to prevent parallel access of SMI.163 * @io_base: base address for registers of SMI.164 * @pdev: platform device165 * @cmd_complete: queue to wait for command completion of NOR-flash.166 * @num_flashes: number of flashes actually present on board.167 * @flash: separate structure for each Serial NOR-flash attached to SMI.168 */169struct spear_smi {170 struct clk *clk;171 u32 status;172 unsigned long clk_rate;173 struct mutex lock;174 void __iomem *io_base;175 struct platform_device *pdev;176 wait_queue_head_t cmd_complete;177 u32 num_flashes;178 struct spear_snor_flash *flash[MAX_NUM_FLASH_CHIP];179};180 181/**182 * struct spear_snor_flash - Structure for Serial NOR Flash183 *184 * @bank: Bank number(0, 1, 2, 3) for each NOR-flash.185 * @dev_id: Device ID of NOR-flash.186 * @lock: lock to manage flash read, write and erase operations187 * @mtd: MTD info for each NOR-flash.188 * @num_parts: Total number of partition in each bank of NOR-flash.189 * @parts: Partition info for each bank of NOR-flash.190 * @page_size: Page size of NOR-flash.191 * @base_addr: Base address of NOR-flash.192 * @erase_cmd: erase command may vary on different flash types193 * @fast_mode: flash supports read in fast mode194 */195struct spear_snor_flash {196 u32 bank;197 u32 dev_id;198 struct mutex lock;199 struct mtd_info mtd;200 u32 num_parts;201 struct mtd_partition *parts;202 u32 page_size;203 void __iomem *base_addr;204 u8 erase_cmd;205 u8 fast_mode;206};207 208static inline struct spear_snor_flash *get_flash_data(struct mtd_info *mtd)209{210 return container_of(mtd, struct spear_snor_flash, mtd);211}212 213/**214 * spear_smi_read_sr - Read status register of flash through SMI215 * @dev: structure of SMI information.216 * @bank: bank to which flash is connected217 *218 * This routine will return the status register of the flash chip present at the219 * given bank.220 */221static int spear_smi_read_sr(struct spear_smi *dev, u32 bank)222{223 int ret;224 u32 ctrlreg1;225 226 mutex_lock(&dev->lock);227 dev->status = 0; /* Will be set in interrupt handler */228 229 ctrlreg1 = readl(dev->io_base + SMI_CR1);230 /* program smi in hw mode */231 writel(ctrlreg1 & ~(SW_MODE | WB_MODE), dev->io_base + SMI_CR1);232 233 /* performing a rsr instruction in hw mode */234 writel((bank << BANK_SHIFT) | RD_STATUS_REG | TFIE,235 dev->io_base + SMI_CR2);236 237 /* wait for tff */238 ret = wait_event_interruptible_timeout(dev->cmd_complete,239 dev->status & TFF, SMI_CMD_TIMEOUT);240 241 /* copy dev->status (lower 16 bits) in order to release lock */242 if (ret > 0)243 ret = dev->status & 0xffff;244 else if (ret == 0)245 ret = -ETIMEDOUT;246 247 /* restore the ctrl regs state */248 writel(ctrlreg1, dev->io_base + SMI_CR1);249 writel(0, dev->io_base + SMI_CR2);250 mutex_unlock(&dev->lock);251 252 return ret;253}254 255/**256 * spear_smi_wait_till_ready - wait till flash is ready257 * @dev: structure of SMI information.258 * @bank: flash corresponding to this bank259 * @timeout: timeout for busy wait condition260 *261 * This routine checks for WIP (write in progress) bit in Status register262 * If successful the routine returns 0 else -EBUSY263 */264static int spear_smi_wait_till_ready(struct spear_smi *dev, u32 bank,265 unsigned long timeout)266{267 unsigned long finish;268 int status;269 270 finish = jiffies + timeout;271 do {272 status = spear_smi_read_sr(dev, bank);273 if (status < 0) {274 if (status == -ETIMEDOUT)275 continue; /* try till finish */276 return status;277 } else if (!(status & SR_WIP)) {278 return 0;279 }280 281 cond_resched();282 } while (!time_after_eq(jiffies, finish));283 284 dev_err(&dev->pdev->dev, "smi controller is busy, timeout\n");285 return -EBUSY;286}287 288/**289 * spear_smi_int_handler - SMI Interrupt Handler.290 * @irq: irq number291 * @dev_id: structure of SMI device, embedded in dev_id.292 *293 * The handler clears all interrupt conditions and records the status in294 * dev->status which is used by the driver later.295 */296static irqreturn_t spear_smi_int_handler(int irq, void *dev_id)297{298 u32 status = 0;299 struct spear_smi *dev = dev_id;300 301 status = readl(dev->io_base + SMI_SR);302 303 if (unlikely(!status))304 return IRQ_NONE;305 306 /* clear all interrupt conditions */307 writel(0, dev->io_base + SMI_SR);308 309 /* copy the status register in dev->status */310 dev->status |= status;311 312 /* send the completion */313 wake_up_interruptible(&dev->cmd_complete);314 315 return IRQ_HANDLED;316}317 318/**319 * spear_smi_hw_init - initializes the smi controller.320 * @dev: structure of smi device321 *322 * this routine initializes the smi controller wit the default values323 */324static void spear_smi_hw_init(struct spear_smi *dev)325{326 unsigned long rate = 0;327 u32 prescale = 0;328 u32 val;329 330 rate = clk_get_rate(dev->clk);331 332 /* functional clock of smi */333 prescale = DIV_ROUND_UP(rate, dev->clk_rate);334 335 /*336 * setting the standard values, fast mode, prescaler for337 * SMI_MAX_CLOCK_FREQ (50MHz) operation and bank enable338 */339 val = HOLD1 | BANK_EN | DSEL_TIME | (prescale << 8);340 341 mutex_lock(&dev->lock);342 /* clear all interrupt conditions */343 writel(0, dev->io_base + SMI_SR);344 345 writel(val, dev->io_base + SMI_CR1);346 mutex_unlock(&dev->lock);347}348 349/**350 * get_flash_index - match chip id from a flash list.351 * @flash_id: a valid nor flash chip id obtained from board.352 *353 * try to validate the chip id by matching from a list, if not found then simply354 * returns negative. In case of success returns index in to the flash devices355 * array.356 */357static int get_flash_index(u32 flash_id)358{359 int index;360 361 /* Matches chip-id to entire list of 'serial-nor flash' ids */362 for (index = 0; index < ARRAY_SIZE(flash_devices); index++) {363 if (flash_devices[index].device_id == flash_id)364 return index;365 }366 367 /* Memory chip is not listed and not supported */368 return -ENODEV;369}370 371/**372 * spear_smi_write_enable - Enable the flash to do write operation373 * @dev: structure of SMI device374 * @bank: enable write for flash connected to this bank375 *376 * Set write enable latch with Write Enable command.377 * Returns 0 on success.378 */379static int spear_smi_write_enable(struct spear_smi *dev, u32 bank)380{381 int ret;382 u32 ctrlreg1;383 384 mutex_lock(&dev->lock);385 dev->status = 0; /* Will be set in interrupt handler */386 387 ctrlreg1 = readl(dev->io_base + SMI_CR1);388 /* program smi in h/w mode */389 writel(ctrlreg1 & ~SW_MODE, dev->io_base + SMI_CR1);390 391 /* give the flash, write enable command */392 writel((bank << BANK_SHIFT) | WE | TFIE, dev->io_base + SMI_CR2);393 394 ret = wait_event_interruptible_timeout(dev->cmd_complete,395 dev->status & TFF, SMI_CMD_TIMEOUT);396 397 /* restore the ctrl regs state */398 writel(ctrlreg1, dev->io_base + SMI_CR1);399 writel(0, dev->io_base + SMI_CR2);400 401 if (ret == 0) {402 ret = -EIO;403 dev_err(&dev->pdev->dev,404 "smi controller failed on write enable\n");405 } else if (ret > 0) {406 /* check whether write mode status is set for required bank */407 if (dev->status & (1 << (bank + WM_SHIFT)))408 ret = 0;409 else {410 dev_err(&dev->pdev->dev, "couldn't enable write\n");411 ret = -EIO;412 }413 }414 415 mutex_unlock(&dev->lock);416 return ret;417}418 419static inline u32420get_sector_erase_cmd(struct spear_snor_flash *flash, u32 offset)421{422 u32 cmd;423 u8 *x = (u8 *)&cmd;424 425 x[0] = flash->erase_cmd;426 x[1] = offset >> 16;427 x[2] = offset >> 8;428 x[3] = offset;429 430 return cmd;431}432 433/**434 * spear_smi_erase_sector - erase one sector of flash435 * @dev: structure of SMI information436 * @command: erase command to be send437 * @bank: bank to which this command needs to be send438 * @bytes: size of command439 *440 * Erase one sector of flash memory at offset ``offset'' which is any441 * address within the sector which should be erased.442 * Returns 0 if successful, non-zero otherwise.443 */444static int spear_smi_erase_sector(struct spear_smi *dev,445 u32 bank, u32 command, u32 bytes)446{447 u32 ctrlreg1 = 0;448 int ret;449 450 ret = spear_smi_wait_till_ready(dev, bank, SMI_MAX_TIME_OUT);451 if (ret)452 return ret;453 454 ret = spear_smi_write_enable(dev, bank);455 if (ret)456 return ret;457 458 mutex_lock(&dev->lock);459 460 ctrlreg1 = readl(dev->io_base + SMI_CR1);461 writel((ctrlreg1 | SW_MODE) & ~WB_MODE, dev->io_base + SMI_CR1);462 463 /* send command in sw mode */464 writel(command, dev->io_base + SMI_TR);465 466 writel((bank << BANK_SHIFT) | SEND | TFIE | (bytes << TX_LEN_SHIFT),467 dev->io_base + SMI_CR2);468 469 ret = wait_event_interruptible_timeout(dev->cmd_complete,470 dev->status & TFF, SMI_CMD_TIMEOUT);471 472 if (ret == 0) {473 ret = -EIO;474 dev_err(&dev->pdev->dev, "sector erase failed\n");475 } else if (ret > 0)476 ret = 0; /* success */477 478 /* restore ctrl regs */479 writel(ctrlreg1, dev->io_base + SMI_CR1);480 writel(0, dev->io_base + SMI_CR2);481 482 mutex_unlock(&dev->lock);483 return ret;484}485 486/**487 * spear_mtd_erase - perform flash erase operation as requested by user488 * @mtd: Provides the memory characteristics489 * @e_info: Provides the erase information490 *491 * Erase an address range on the flash chip. The address range may extend492 * one or more erase sectors. Return an error is there is a problem erasing.493 */494static int spear_mtd_erase(struct mtd_info *mtd, struct erase_info *e_info)495{496 struct spear_snor_flash *flash = get_flash_data(mtd);497 struct spear_smi *dev = mtd->priv;498 u32 addr, command, bank;499 int len, ret;500 501 if (!flash || !dev)502 return -ENODEV;503 504 bank = flash->bank;505 if (bank > dev->num_flashes - 1) {506 dev_err(&dev->pdev->dev, "Invalid Bank Num");507 return -EINVAL;508 }509 510 addr = e_info->addr;511 len = e_info->len;512 513 mutex_lock(&flash->lock);514 515 /* now erase sectors in loop */516 while (len) {517 command = get_sector_erase_cmd(flash, addr);518 /* preparing the command for flash */519 ret = spear_smi_erase_sector(dev, bank, command, 4);520 if (ret) {521 mutex_unlock(&flash->lock);522 return ret;523 }524 addr += mtd->erasesize;525 len -= mtd->erasesize;526 }527 528 mutex_unlock(&flash->lock);529 530 return 0;531}532 533/**534 * spear_mtd_read - performs flash read operation as requested by the user535 * @mtd: MTD information of the memory bank536 * @from: Address from which to start read537 * @len: Number of bytes to be read538 * @retlen: Fills the Number of bytes actually read539 * @buf: Fills this after reading540 *541 * Read an address range from the flash chip. The address range542 * may be any size provided it is within the physical boundaries.543 * Returns 0 on success, non zero otherwise544 */545static int spear_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,546 size_t *retlen, u8 *buf)547{548 struct spear_snor_flash *flash = get_flash_data(mtd);549 struct spear_smi *dev = mtd->priv;550 void __iomem *src;551 u32 ctrlreg1, val;552 int ret;553 554 if (!flash || !dev)555 return -ENODEV;556 557 if (flash->bank > dev->num_flashes - 1) {558 dev_err(&dev->pdev->dev, "Invalid Bank Num");559 return -EINVAL;560 }561 562 /* select address as per bank number */563 src = flash->base_addr + from;564 565 mutex_lock(&flash->lock);566 567 /* wait till previous write/erase is done. */568 ret = spear_smi_wait_till_ready(dev, flash->bank, SMI_MAX_TIME_OUT);569 if (ret) {570 mutex_unlock(&flash->lock);571 return ret;572 }573 574 mutex_lock(&dev->lock);575 /* put smi in hw mode not wbt mode */576 ctrlreg1 = val = readl(dev->io_base + SMI_CR1);577 val &= ~(SW_MODE | WB_MODE);578 if (flash->fast_mode)579 val |= FAST_MODE;580 581 writel(val, dev->io_base + SMI_CR1);582 583 memcpy_fromio(buf, src, len);584 585 /* restore ctrl reg1 */586 writel(ctrlreg1, dev->io_base + SMI_CR1);587 mutex_unlock(&dev->lock);588 589 *retlen = len;590 mutex_unlock(&flash->lock);591 592 return 0;593}594 595/*596 * The purpose of this function is to ensure a memcpy_toio() with byte writes597 * only. Its structure is inspired from the ARM implementation of _memcpy_toio()598 * which also does single byte writes but cannot be used here as this is just an599 * implementation detail and not part of the API. Not mentioning the comment600 * stating that _memcpy_toio() should be optimized.601 */602static void spear_smi_memcpy_toio_b(volatile void __iomem *dest,603 const void *src, size_t len)604{605 const unsigned char *from = src;606 607 while (len) {608 len--;609 writeb(*from, dest);610 from++;611 dest++;612 }613}614 615static inline int spear_smi_cpy_toio(struct spear_smi *dev, u32 bank,616 void __iomem *dest, const void *src, size_t len)617{618 int ret;619 u32 ctrlreg1;620 621 /* wait until finished previous write command. */622 ret = spear_smi_wait_till_ready(dev, bank, SMI_MAX_TIME_OUT);623 if (ret)624 return ret;625 626 /* put smi in write enable */627 ret = spear_smi_write_enable(dev, bank);628 if (ret)629 return ret;630 631 /* put smi in hw, write burst mode */632 mutex_lock(&dev->lock);633 634 ctrlreg1 = readl(dev->io_base + SMI_CR1);635 writel((ctrlreg1 | WB_MODE) & ~SW_MODE, dev->io_base + SMI_CR1);636 637 /*638 * In Write Burst mode (WB_MODE), the specs states that writes must be:639 * - incremental640 * - of the same size641 * The ARM implementation of memcpy_toio() will optimize the number of642 * I/O by using as much 4-byte writes as possible, surrounded by643 * 2-byte/1-byte access if:644 * - the destination is not 4-byte aligned645 * - the length is not a multiple of 4-byte.646 * Avoid this alternance of write access size by using our own 'byte647 * access' helper if at least one of the two conditions above is true.648 */649 if (IS_ALIGNED(len, sizeof(u32)) &&650 IS_ALIGNED((uintptr_t)dest, sizeof(u32)))651 memcpy_toio(dest, src, len);652 else653 spear_smi_memcpy_toio_b(dest, src, len);654 655 writel(ctrlreg1, dev->io_base + SMI_CR1);656 657 mutex_unlock(&dev->lock);658 return 0;659}660 661/**662 * spear_mtd_write - performs write operation as requested by the user.663 * @mtd: MTD information of the memory bank.664 * @to: Address to write.665 * @len: Number of bytes to be written.666 * @retlen: Number of bytes actually wrote.667 * @buf: Buffer from which the data to be taken.668 *669 * Write an address range to the flash chip. Data must be written in670 * flash_page_size chunks. The address range may be any size provided671 * it is within the physical boundaries.672 * Returns 0 on success, non zero otherwise673 */674static int spear_mtd_write(struct mtd_info *mtd, loff_t to, size_t len,675 size_t *retlen, const u8 *buf)676{677 struct spear_snor_flash *flash = get_flash_data(mtd);678 struct spear_smi *dev = mtd->priv;679 void __iomem *dest;680 u32 page_offset, page_size;681 int ret;682 683 if (!flash || !dev)684 return -ENODEV;685 686 if (flash->bank > dev->num_flashes - 1) {687 dev_err(&dev->pdev->dev, "Invalid Bank Num");688 return -EINVAL;689 }690 691 /* select address as per bank number */692 dest = flash->base_addr + to;693 mutex_lock(&flash->lock);694 695 page_offset = (u32)to % flash->page_size;696 697 /* do if all the bytes fit onto one page */698 if (page_offset + len <= flash->page_size) {699 ret = spear_smi_cpy_toio(dev, flash->bank, dest, buf, len);700 if (!ret)701 *retlen += len;702 } else {703 u32 i;704 705 /* the size of data remaining on the first page */706 page_size = flash->page_size - page_offset;707 708 ret = spear_smi_cpy_toio(dev, flash->bank, dest, buf,709 page_size);710 if (ret)711 goto err_write;712 else713 *retlen += page_size;714 715 /* write everything in pagesize chunks */716 for (i = page_size; i < len; i += page_size) {717 page_size = len - i;718 if (page_size > flash->page_size)719 page_size = flash->page_size;720 721 ret = spear_smi_cpy_toio(dev, flash->bank, dest + i,722 buf + i, page_size);723 if (ret)724 break;725 else726 *retlen += page_size;727 }728 }729 730err_write:731 mutex_unlock(&flash->lock);732 733 return ret;734}735 736/**737 * spear_smi_probe_flash - Detects the NOR Flash chip.738 * @dev: structure of SMI information.739 * @bank: bank on which flash must be probed740 *741 * This routine will check whether there exists a flash chip on a given memory742 * bank ID.743 * Return index of the probed flash in flash devices structure744 */745static int spear_smi_probe_flash(struct spear_smi *dev, u32 bank)746{747 int ret;748 u32 val = 0;749 750 ret = spear_smi_wait_till_ready(dev, bank, SMI_PROBE_TIMEOUT);751 if (ret)752 return ret;753 754 mutex_lock(&dev->lock);755 756 dev->status = 0; /* Will be set in interrupt handler */757 /* put smi in sw mode */758 val = readl(dev->io_base + SMI_CR1);759 writel(val | SW_MODE, dev->io_base + SMI_CR1);760 761 /* send readid command in sw mode */762 writel(OPCODE_RDID, dev->io_base + SMI_TR);763 764 val = (bank << BANK_SHIFT) | SEND | (1 << TX_LEN_SHIFT) |765 (3 << RX_LEN_SHIFT) | TFIE;766 writel(val, dev->io_base + SMI_CR2);767 768 /* wait for TFF */769 ret = wait_event_interruptible_timeout(dev->cmd_complete,770 dev->status & TFF, SMI_CMD_TIMEOUT);771 if (ret <= 0) {772 ret = -ENODEV;773 goto err_probe;774 }775 776 /* get memory chip id */777 val = readl(dev->io_base + SMI_RR);778 val &= 0x00ffffff;779 ret = get_flash_index(val);780 781err_probe:782 /* clear sw mode */783 val = readl(dev->io_base + SMI_CR1);784 writel(val & ~SW_MODE, dev->io_base + SMI_CR1);785 786 mutex_unlock(&dev->lock);787 return ret;788}789 790 791#ifdef CONFIG_OF792static int spear_smi_probe_config_dt(struct platform_device *pdev,793 struct device_node *np)794{795 struct spear_smi_plat_data *pdata = dev_get_platdata(&pdev->dev);796 struct device_node *pp;797 const __be32 *addr;798 u32 val;799 int len;800 int i = 0;801 802 if (!np)803 return -ENODEV;804 805 of_property_read_u32(np, "clock-rate", &val);806 pdata->clk_rate = val;807 808 pdata->board_flash_info = devm_kzalloc(&pdev->dev,809 sizeof(*pdata->board_flash_info),810 GFP_KERNEL);811 if (!pdata->board_flash_info)812 return -ENOMEM;813 814 /* Fill structs for each subnode (flash device) */815 for_each_child_of_node(np, pp) {816 pdata->np[i] = pp;817 818 /* Read base-addr and size from DT */819 addr = of_get_property(pp, "reg", &len);820 pdata->board_flash_info->mem_base = be32_to_cpup(&addr[0]);821 pdata->board_flash_info->size = be32_to_cpup(&addr[1]);822 823 pdata->board_flash_info->fast_mode =824 of_property_read_bool(pp, "st,smi-fast-mode");825 826 i++;827 }828 829 pdata->num_flashes = i;830 831 return 0;832}833#else834static int spear_smi_probe_config_dt(struct platform_device *pdev,835 struct device_node *np)836{837 return -ENOSYS;838}839#endif840 841static int spear_smi_setup_banks(struct platform_device *pdev,842 u32 bank, struct device_node *np)843{844 struct spear_smi *dev = platform_get_drvdata(pdev);845 struct spear_smi_flash_info *flash_info;846 struct spear_smi_plat_data *pdata;847 struct spear_snor_flash *flash;848 struct mtd_partition *parts = NULL;849 int count = 0;850 int flash_index;851 int ret = 0;852 853 pdata = dev_get_platdata(&pdev->dev);854 if (bank > pdata->num_flashes - 1)855 return -EINVAL;856 857 flash_info = &pdata->board_flash_info[bank];858 if (!flash_info)859 return -ENODEV;860 861 flash = devm_kzalloc(&pdev->dev, sizeof(*flash), GFP_ATOMIC);862 if (!flash)863 return -ENOMEM;864 flash->bank = bank;865 flash->fast_mode = flash_info->fast_mode ? 1 : 0;866 mutex_init(&flash->lock);867 868 /* verify whether nor flash is really present on board */869 flash_index = spear_smi_probe_flash(dev, bank);870 if (flash_index < 0) {871 dev_info(&dev->pdev->dev, "smi-nor%d not found\n", bank);872 return flash_index;873 }874 /* map the memory for nor flash chip */875 flash->base_addr = devm_ioremap(&pdev->dev, flash_info->mem_base,876 flash_info->size);877 if (!flash->base_addr)878 return -EIO;879 880 dev->flash[bank] = flash;881 flash->mtd.priv = dev;882 883 if (flash_info->name)884 flash->mtd.name = flash_info->name;885 else886 flash->mtd.name = flash_devices[flash_index].name;887 888 flash->mtd.dev.parent = &pdev->dev;889 mtd_set_of_node(&flash->mtd, np);890 flash->mtd.type = MTD_NORFLASH;891 flash->mtd.writesize = 1;892 flash->mtd.flags = MTD_CAP_NORFLASH;893 flash->mtd.size = flash_info->size;894 flash->mtd.erasesize = flash_devices[flash_index].sectorsize;895 flash->page_size = flash_devices[flash_index].pagesize;896 flash->mtd.writebufsize = flash->page_size;897 flash->erase_cmd = flash_devices[flash_index].erase_cmd;898 flash->mtd._erase = spear_mtd_erase;899 flash->mtd._read = spear_mtd_read;900 flash->mtd._write = spear_mtd_write;901 flash->dev_id = flash_devices[flash_index].device_id;902 903 dev_info(&dev->pdev->dev, "mtd .name=%s .size=%llx(%lluM)\n",904 flash->mtd.name, flash->mtd.size,905 flash->mtd.size / (1024 * 1024));906 907 dev_info(&dev->pdev->dev, ".erasesize = 0x%x(%uK)\n",908 flash->mtd.erasesize, flash->mtd.erasesize / 1024);909 910#ifndef CONFIG_OF911 if (flash_info->partitions) {912 parts = flash_info->partitions;913 count = flash_info->nr_partitions;914 }915#endif916 917 ret = mtd_device_register(&flash->mtd, parts, count);918 if (ret) {919 dev_err(&dev->pdev->dev, "Err MTD partition=%d\n", ret);920 return ret;921 }922 923 return 0;924}925 926/**927 * spear_smi_probe - Entry routine928 * @pdev: platform device structure929 *930 * This is the first routine which gets invoked during booting and does all931 * initialization/allocation work. The routine looks for available memory banks,932 * and do proper init for any found one.933 * Returns 0 on success, non zero otherwise934 */935static int spear_smi_probe(struct platform_device *pdev)936{937 struct device_node *np = pdev->dev.of_node;938 struct spear_smi_plat_data *pdata = NULL;939 struct spear_smi *dev;940 int irq, ret = 0;941 int i;942 943 if (np) {944 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);945 if (!pdata) {946 ret = -ENOMEM;947 goto err;948 }949 pdev->dev.platform_data = pdata;950 ret = spear_smi_probe_config_dt(pdev, np);951 if (ret) {952 ret = -ENODEV;953 dev_err(&pdev->dev, "no platform data\n");954 goto err;955 }956 } else {957 pdata = dev_get_platdata(&pdev->dev);958 if (!pdata) {959 ret = -ENODEV;960 dev_err(&pdev->dev, "no platform data\n");961 goto err;962 }963 }964 965 irq = platform_get_irq(pdev, 0);966 if (irq < 0) {967 ret = -ENODEV;968 goto err;969 }970 971 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);972 if (!dev) {973 ret = -ENOMEM;974 goto err;975 }976 977 dev->io_base = devm_platform_ioremap_resource(pdev, 0);978 if (IS_ERR(dev->io_base)) {979 ret = PTR_ERR(dev->io_base);980 goto err;981 }982 983 dev->pdev = pdev;984 dev->clk_rate = pdata->clk_rate;985 986 if (dev->clk_rate > SMI_MAX_CLOCK_FREQ)987 dev->clk_rate = SMI_MAX_CLOCK_FREQ;988 989 dev->num_flashes = pdata->num_flashes;990 991 if (dev->num_flashes > MAX_NUM_FLASH_CHIP) {992 dev_err(&pdev->dev, "exceeding max number of flashes\n");993 dev->num_flashes = MAX_NUM_FLASH_CHIP;994 }995 996 dev->clk = devm_clk_get_enabled(&pdev->dev, NULL);997 if (IS_ERR(dev->clk)) {998 ret = PTR_ERR(dev->clk);999 goto err;1000 }1001 1002 ret = devm_request_irq(&pdev->dev, irq, spear_smi_int_handler, 0,1003 pdev->name, dev);1004 if (ret) {1005 dev_err(&dev->pdev->dev, "SMI IRQ allocation failed\n");1006 goto err;1007 }1008 1009 mutex_init(&dev->lock);1010 init_waitqueue_head(&dev->cmd_complete);1011 spear_smi_hw_init(dev);1012 platform_set_drvdata(pdev, dev);1013 1014 /* loop for each serial nor-flash which is connected to smi */1015 for (i = 0; i < dev->num_flashes; i++) {1016 ret = spear_smi_setup_banks(pdev, i, pdata->np[i]);1017 if (ret) {1018 dev_err(&dev->pdev->dev, "bank setup failed\n");1019 goto err;1020 }1021 }1022 1023 return 0;1024err:1025 return ret;1026}1027 1028/**1029 * spear_smi_remove - Exit routine1030 * @pdev: platform device structure1031 *1032 * free all allocations and delete the partitions.1033 */1034static void spear_smi_remove(struct platform_device *pdev)1035{1036 struct spear_smi *dev;1037 struct spear_snor_flash *flash;1038 int i;1039 1040 dev = platform_get_drvdata(pdev);1041 1042 /* clean up for all nor flash */1043 for (i = 0; i < dev->num_flashes; i++) {1044 flash = dev->flash[i];1045 if (!flash)1046 continue;1047 1048 /* clean up mtd stuff */1049 WARN_ON(mtd_device_unregister(&flash->mtd));1050 }1051}1052 1053#ifdef CONFIG_PM_SLEEP1054static int spear_smi_suspend(struct device *dev)1055{1056 struct spear_smi *sdev = dev_get_drvdata(dev);1057 1058 if (sdev && sdev->clk)1059 clk_disable_unprepare(sdev->clk);1060 1061 return 0;1062}1063 1064static int spear_smi_resume(struct device *dev)1065{1066 struct spear_smi *sdev = dev_get_drvdata(dev);1067 int ret = -EPERM;1068 1069 if (sdev && sdev->clk)1070 ret = clk_prepare_enable(sdev->clk);1071 1072 if (!ret)1073 spear_smi_hw_init(sdev);1074 return ret;1075}1076#endif1077 1078static SIMPLE_DEV_PM_OPS(spear_smi_pm_ops, spear_smi_suspend, spear_smi_resume);1079 1080#ifdef CONFIG_OF1081static const struct of_device_id spear_smi_id_table[] = {1082 { .compatible = "st,spear600-smi" },1083 {}1084};1085MODULE_DEVICE_TABLE(of, spear_smi_id_table);1086#endif1087 1088static struct platform_driver spear_smi_driver = {1089 .driver = {1090 .name = "smi",1091 .bus = &platform_bus_type,1092 .of_match_table = of_match_ptr(spear_smi_id_table),1093 .pm = &spear_smi_pm_ops,1094 },1095 .probe = spear_smi_probe,1096 .remove_new = spear_smi_remove,1097};1098module_platform_driver(spear_smi_driver);1099 1100MODULE_LICENSE("GPL");1101MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim <shiraz.linux.kernel@gmail.com>");1102MODULE_DESCRIPTION("MTD SMI driver for serial nor flash chips");1103