aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/devices
diff options
context:
space:
mode:
authorShiraz Hashim <shiraz.hashim@st.com>2012-01-12 08:38:57 -0500
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-03-26 19:14:16 -0400
commitf18dbbb1bfe06ea3995b55c2f533057da9e9294a (patch)
tree03977f824b653bdaff5638429b6f6bd84577da4e /drivers/mtd/devices
parent661a08327d11bcc4cf649c5ae4bdf2db0a87b320 (diff)
mtd: ST SPEAr: Add SMI driver for serial NOR flash
SPEAr platforms (spear3xx/spear6xx/spear13xx) provide SMI (Serial Memory Interface) controller to access serial NOR flash. SMI provides a simple interface for SPI/serial NOR flashes and has certain inbuilt commands and features to support these flashes easily. It also makes it possible to map an address range in order to directly access (read/write) the SNOR over address bus. This patch intends to provide serial nor driver support for spear platforms which are accessed through SMI. Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com> Signed-off-by: Viresh Kumar <viresh.kumar@st.com> Signed-off-by: Stefan Roese <sr@denx.de> Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@linux.intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/devices')
-rw-r--r--drivers/mtd/devices/Kconfig7
-rw-r--r--drivers/mtd/devices/Makefile1
-rw-r--r--drivers/mtd/devices/spear_smi.c1112
3 files changed, 1120 insertions, 0 deletions
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 37b05c3f2792..98206b034c01 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -102,6 +102,13 @@ config M25PXX_USE_FAST_READ
102 help 102 help
103 This option enables FAST_READ access supported by ST M25Pxx. 103 This option enables FAST_READ access supported by ST M25Pxx.
104 104
105config MTD_SPEAR_SMI
106 tristate "SPEAR MTD NOR Support through SMI controller"
107 depends on PLAT_SPEAR
108 default y
109 help
110 This enable SNOR support on SPEAR platforms using SMI controller
111
105config MTD_SST25L 112config MTD_SST25L
106 tristate "Support SST25L (non JEDEC) SPI Flash chips" 113 tristate "Support SST25L (non JEDEC) SPI Flash chips"
107 depends on SPI_MASTER 114 depends on SPI_MASTER
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index 56c7cd462f11..a4dd1d822b6c 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_MTD_LART) += lart.o
17obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o 17obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o
18obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o 18obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o
19obj-$(CONFIG_MTD_M25P80) += m25p80.o 19obj-$(CONFIG_MTD_M25P80) += m25p80.o
20obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o
20obj-$(CONFIG_MTD_SST25L) += sst25l.o 21obj-$(CONFIG_MTD_SST25L) += sst25l.o
21 22
22CFLAGS_docg3.o += -I$(src) \ No newline at end of file 23CFLAGS_docg3.o += -I$(src) \ No newline at end of file
diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c
new file mode 100644
index 000000000000..1eac56cf8ed6
--- /dev/null
+++ b/drivers/mtd/devices/spear_smi.c
@@ -0,0 +1,1112 @@
1/*
2 * SMI (Serial Memory Controller) device driver for Serial NOR Flash on
3 * SPEAr platform
4 * The serial nor interface is largely based on drivers/mtd/m25p80.c,
5 * however the SPI interface has been replaced by SMI.
6 *
7 * Copyright © 2010 STMicroelectronics.
8 * Ashish Priyadarshi
9 * Shiraz Hashim <shiraz.hashim@st.com>
10 *
11 * This file is licensed under the terms of the GNU General Public
12 * License version 2. This program is licensed "as is" without any
13 * 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/mtd/mtd.h>
30#include <linux/mtd/partitions.h>
31#include <linux/mtd/spear_smi.h>
32#include <linux/mutex.h>
33#include <linux/sched.h>
34#include <linux/slab.h>
35#include <linux/wait.h>
36
37/* max possible slots for serial-nor flash chip in the SMI controller */
38#define MAX_NUM_FLASH_CHIP 4
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 0
73#define RX_LEN_SHIFT 4
74#define BANK_SHIFT 12
75
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 12
89
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/* These partitions would be used if platform doesn't pass one */
153static struct mtd_partition part_info_8M[] = {
154 DEFINE_PARTS("Xloader", 0x00, 0x10000),
155 DEFINE_PARTS("UBoot", MTDPART_OFS_APPEND, 0x40000),
156 DEFINE_PARTS("Kernel", MTDPART_OFS_APPEND, 0x2C0000),
157 DEFINE_PARTS("Root File System", MTDPART_OFS_APPEND, MTDPART_SIZ_FULL),
158};
159
160static struct mtd_partition part_info_16M[] = {
161 DEFINE_PARTS("Xloader", 0x00, 0x40000),
162 DEFINE_PARTS("UBoot", MTDPART_OFS_APPEND, 0x100000),
163 DEFINE_PARTS("Kernel", MTDPART_OFS_APPEND, 0x300000),
164 DEFINE_PARTS("Root File System", MTDPART_OFS_APPEND, MTDPART_SIZ_FULL),
165};
166
167/* Define spear specific structures */
168
169struct spear_snor_flash;
170
171/**
172 * struct spear_smi - Structure for SMI Device
173 *
174 * @clk: functional clock
175 * @status: current status register of SMI.
176 * @clk_rate: functional clock rate of SMI (default: SMI_MAX_CLOCK_FREQ)
177 * @lock: lock to prevent parallel access of SMI.
178 * @io_base: base address for registers of SMI.
179 * @pdev: platform device
180 * @cmd_complete: queue to wait for command completion of NOR-flash.
181 * @num_flashes: number of flashes actually present on board.
182 * @flash: separate structure for each Serial NOR-flash attached to SMI.
183 */
184struct spear_smi {
185 struct clk *clk;
186 u32 status;
187 unsigned long clk_rate;
188 struct mutex lock;
189 void __iomem *io_base;
190 struct platform_device *pdev;
191 wait_queue_head_t cmd_complete;
192 u32 num_flashes;
193 struct spear_snor_flash *flash[MAX_NUM_FLASH_CHIP];
194};
195
196/**
197 * struct spear_snor_flash - Structure for Serial NOR Flash
198 *
199 * @bank: Bank number(0, 1, 2, 3) for each NOR-flash.
200 * @dev_id: Device ID of NOR-flash.
201 * @lock: lock to manage flash read, write and erase operations
202 * @mtd: MTD info for each NOR-flash.
203 * @num_parts: Total number of partition in each bank of NOR-flash.
204 * @parts: Partition info for each bank of NOR-flash.
205 * @page_size: Page size of NOR-flash.
206 * @base_addr: Base address of NOR-flash.
207 * @erase_cmd: erase command may vary on different flash types
208 * @fast_mode: flash supports read in fast mode
209 */
210struct spear_snor_flash {
211 u32 bank;
212 u32 dev_id;
213 struct mutex lock;
214 struct mtd_info mtd;
215 u32 num_parts;
216 struct mtd_partition *parts;
217 u32 page_size;
218 void __iomem *base_addr;
219 u8 erase_cmd;
220 u8 fast_mode;
221};
222
223static inline struct spear_snor_flash *get_flash_data(struct mtd_info *mtd)
224{
225 return container_of(mtd, struct spear_snor_flash, mtd);
226}
227
228/**
229 * spear_smi_read_sr - Read status register of flash through SMI
230 * @dev: structure of SMI information.
231 * @bank: bank to which flash is connected
232 *
233 * This routine will return the status register of the flash chip present at the
234 * given bank.
235 */
236static int spear_smi_read_sr(struct spear_smi *dev, u32 bank)
237{
238 int ret;
239 u32 ctrlreg1;
240
241 mutex_lock(&dev->lock);
242 dev->status = 0; /* Will be set in interrupt handler */
243
244 ctrlreg1 = readl(dev->io_base + SMI_CR1);
245 /* program smi in hw mode */
246 writel(ctrlreg1 & ~(SW_MODE | WB_MODE), dev->io_base + SMI_CR1);
247
248 /* performing a rsr instruction in hw mode */
249 writel((bank << BANK_SHIFT) | RD_STATUS_REG | TFIE,
250 dev->io_base + SMI_CR2);
251
252 /* wait for tff */
253 ret = wait_event_interruptible_timeout(dev->cmd_complete,
254 dev->status & TFF, SMI_CMD_TIMEOUT);
255
256 /* copy dev->status (lower 16 bits) in order to release lock */
257 if (ret > 0)
258 ret = dev->status & 0xffff;
259 else
260 ret = -EIO;
261
262 /* restore the ctrl regs state */
263 writel(ctrlreg1, dev->io_base + SMI_CR1);
264 writel(0, dev->io_base + SMI_CR2);
265 mutex_unlock(&dev->lock);
266
267 return ret;
268}
269
270/**
271 * spear_smi_wait_till_ready - wait till flash is ready
272 * @dev: structure of SMI information.
273 * @bank: flash corresponding to this bank
274 * @timeout: timeout for busy wait condition
275 *
276 * This routine checks for WIP (write in progress) bit in Status register
277 * If successful the routine returns 0 else -EBUSY
278 */
279static int spear_smi_wait_till_ready(struct spear_smi *dev, u32 bank,
280 unsigned long timeout)
281{
282 unsigned long finish;
283 int status;
284
285 finish = jiffies + timeout;
286 do {
287 status = spear_smi_read_sr(dev, bank);
288 if (status < 0)
289 continue; /* try till timeout */
290 else if (!(status & SR_WIP))
291 return 0;
292
293 cond_resched();
294 } while (!time_after_eq(jiffies, finish));
295
296 dev_err(&dev->pdev->dev, "smi controller is busy, timeout\n");
297 return status;
298}
299
300/**
301 * spear_smi_int_handler - SMI Interrupt Handler.
302 * @irq: irq number
303 * @dev_id: structure of SMI device, embedded in dev_id.
304 *
305 * The handler clears all interrupt conditions and records the status in
306 * dev->status which is used by the driver later.
307 */
308static irqreturn_t spear_smi_int_handler(int irq, void *dev_id)
309{
310 u32 status = 0;
311 struct spear_smi *dev = dev_id;
312
313 status = readl(dev->io_base + SMI_SR);
314
315 if (unlikely(!status))
316 return IRQ_NONE;
317
318 /* clear all interrupt conditions */
319 writel(0, dev->io_base + SMI_SR);
320
321 /* copy the status register in dev->status */
322 dev->status |= status;
323
324 /* send the completion */
325 wake_up_interruptible(&dev->cmd_complete);
326
327 return IRQ_HANDLED;
328}
329
330/**
331 * spear_smi_hw_init - initializes the smi controller.
332 * @dev: structure of smi device
333 *
334 * this routine initializes the smi controller wit the default values
335 */
336static void spear_smi_hw_init(struct spear_smi *dev)
337{
338 unsigned long rate = 0;
339 u32 prescale = 0;
340 u32 val;
341
342 rate = clk_get_rate(dev->clk);
343
344 /* functional clock of smi */
345 prescale = DIV_ROUND_UP(rate, dev->clk_rate);
346
347 /*
348 * setting the standard values, fast mode, prescaler for
349 * SMI_MAX_CLOCK_FREQ (50MHz) operation and bank enable
350 */
351 val = HOLD1 | BANK_EN | DSEL_TIME | (prescale << 8);
352
353 mutex_lock(&dev->lock);
354 writel(val, dev->io_base + SMI_CR1);
355 mutex_unlock(&dev->lock);
356}
357
358/**
359 * get_flash_index - match chip id from a flash list.
360 * @flash_id: a valid nor flash chip id obtained from board.
361 *
362 * try to validate the chip id by matching from a list, if not found then simply
363 * returns negative. In case of success returns index in to the flash devices
364 * array.
365 */
366static int get_flash_index(u32 flash_id)
367{
368 int index;
369
370 /* Matches chip-id to entire list of 'serial-nor flash' ids */
371 for (index = 0; index < ARRAY_SIZE(flash_devices); index++) {
372 if (flash_devices[index].device_id == flash_id)
373 return index;
374 }
375
376 /* Memory chip is not listed and not supported */
377 return -ENODEV;
378}
379
380/**
381 * spear_smi_write_enable - Enable the flash to do write operation
382 * @dev: structure of SMI device
383 * @bank: enable write for flash connected to this bank
384 *
385 * Set write enable latch with Write Enable command.
386 * Returns 0 on success.
387 */
388static int spear_smi_write_enable(struct spear_smi *dev, u32 bank)
389{
390 int ret;
391 u32 ctrlreg1;
392
393 mutex_lock(&dev->lock);
394 dev->status = 0; /* Will be set in interrupt handler */
395
396 ctrlreg1 = readl(dev->io_base + SMI_CR1);
397 /* program smi in h/w mode */
398 writel(ctrlreg1 & ~SW_MODE, dev->io_base + SMI_CR1);
399
400 /* give the flash, write enable command */
401 writel((bank << BANK_SHIFT) | WE | TFIE, dev->io_base + SMI_CR2);
402
403 ret = wait_event_interruptible_timeout(dev->cmd_complete,
404 dev->status & TFF, SMI_CMD_TIMEOUT);
405
406 /* restore the ctrl regs state */
407 writel(ctrlreg1, dev->io_base + SMI_CR1);
408 writel(0, dev->io_base + SMI_CR2);
409
410 if (ret <= 0) {
411 ret = -EIO;
412 dev_err(&dev->pdev->dev,
413 "smi controller failed on write enable\n");
414 } else {
415 /* check whether write mode status is set for required bank */
416 if (dev->status & (1 << (bank + WM_SHIFT)))
417 ret = 0;
418 else {
419 dev_err(&dev->pdev->dev, "couldn't enable write\n");
420 ret = -EIO;
421 }
422 }
423
424 mutex_unlock(&dev->lock);
425 return ret;
426}
427
428static inline u32
429get_sector_erase_cmd(struct spear_snor_flash *flash, u32 offset)
430{
431 u32 cmd;
432 u8 *x = (u8 *)&cmd;
433
434 x[0] = flash->erase_cmd;
435 x[1] = offset >> 16;
436 x[2] = offset >> 8;
437 x[3] = offset;
438
439 return cmd;
440}
441
442/**
443 * spear_smi_erase_sector - erase one sector of flash
444 * @dev: structure of SMI information
445 * @command: erase command to be send
446 * @bank: bank to which this command needs to be send
447 * @bytes: size of command
448 *
449 * Erase one sector of flash memory at offset ``offset'' which is any
450 * address within the sector which should be erased.
451 * Returns 0 if successful, non-zero otherwise.
452 */
453static int spear_smi_erase_sector(struct spear_smi *dev,
454 u32 bank, u32 command, u32 bytes)
455{
456 u32 ctrlreg1 = 0;
457 int ret;
458
459 ret = spear_smi_wait_till_ready(dev, bank, SMI_MAX_TIME_OUT);
460 if (ret)
461 return ret;
462
463 ret = spear_smi_write_enable(dev, bank);
464 if (ret)
465 return ret;
466
467 mutex_lock(&dev->lock);
468
469 ctrlreg1 = readl(dev->io_base + SMI_CR1);
470 writel((ctrlreg1 | SW_MODE) & ~WB_MODE, dev->io_base + SMI_CR1);
471
472 /* send command in sw mode */
473 writel(command, dev->io_base + SMI_TR);
474
475 writel((bank << BANK_SHIFT) | SEND | TFIE | (bytes << TX_LEN_SHIFT),
476 dev->io_base + SMI_CR2);
477
478 ret = wait_event_interruptible_timeout(dev->cmd_complete,
479 dev->status & TFF, SMI_CMD_TIMEOUT);
480
481 if (ret <= 0) {
482 ret = -EIO;
483 dev_err(&dev->pdev->dev, "sector erase failed\n");
484 } else
485 ret = 0; /* success */
486
487 /* restore ctrl regs */
488 writel(ctrlreg1, dev->io_base + SMI_CR1);
489 writel(0, dev->io_base + SMI_CR2);
490
491 mutex_unlock(&dev->lock);
492 return ret;
493}
494
495/**
496 * spear_mtd_erase - perform flash erase operation as requested by user
497 * @mtd: Provides the memory characteristics
498 * @e_info: Provides the erase information
499 *
500 * Erase an address range on the flash chip. The address range may extend
501 * one or more erase sectors. Return an error is there is a problem erasing.
502 */
503static int spear_mtd_erase(struct mtd_info *mtd, struct erase_info *e_info)
504{
505 struct spear_snor_flash *flash = get_flash_data(mtd);
506 struct spear_smi *dev = mtd->priv;
507 u32 addr, command, bank;
508 int len, ret;
509
510 if (!flash || !dev)
511 return -ENODEV;
512
513 /* do not allow erase past end of device */
514 if (e_info->addr + e_info->len > flash->mtd.size)
515 return -EINVAL;
516
517 bank = flash->bank;
518 if (bank > dev->num_flashes - 1) {
519 dev_err(&dev->pdev->dev, "Invalid Bank Num");
520 return -EINVAL;
521 }
522
523 addr = e_info->addr;
524 len = e_info->len;
525
526 mutex_lock(&flash->lock);
527
528 /* now erase sectors in loop */
529 while (len) {
530 command = get_sector_erase_cmd(flash, addr);
531 /* preparing the command for flash */
532 ret = spear_smi_erase_sector(dev, bank, command, 4);
533 if (ret) {
534 e_info->state = MTD_ERASE_FAILED;
535 mutex_unlock(&flash->lock);
536 return ret;
537 }
538 addr += mtd->erasesize;
539 len -= mtd->erasesize;
540 }
541
542 mutex_unlock(&flash->lock);
543 e_info->state = MTD_ERASE_DONE;
544 mtd_erase_callback(e_info);
545
546 return 0;
547}
548
549/**
550 * spear_mtd_read - performs flash read operation as requested by the user
551 * @mtd: MTD information of the memory bank
552 * @from: Address from which to start read
553 * @len: Number of bytes to be read
554 * @retlen: Fills the Number of bytes actually read
555 * @buf: Fills this after reading
556 *
557 * Read an address range from the flash chip. The address range
558 * may be any size provided it is within the physical boundaries.
559 * Returns 0 on success, non zero otherwise
560 */
561static int spear_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
562 size_t *retlen, u8 *buf)
563{
564 struct spear_snor_flash *flash = get_flash_data(mtd);
565 struct spear_smi *dev = mtd->priv;
566 void *src;
567 u32 ctrlreg1, val;
568 int ret;
569
570 if (!len)
571 return 0;
572
573 if (!flash || !dev)
574 return -ENODEV;
575
576 /* do not allow reads past end of device */
577 if (from + len > flash->mtd.size)
578 return -EINVAL;
579
580 if (flash->bank > dev->num_flashes - 1) {
581 dev_err(&dev->pdev->dev, "Invalid Bank Num");
582 return -EINVAL;
583 }
584
585 if (!retlen)
586 return -EINVAL;
587 else
588 *retlen = 0;
589
590 /* select address as per bank number */
591 src = flash->base_addr + from;
592
593 mutex_lock(&flash->lock);
594
595 /* wait till previous write/erase is done. */
596 ret = spear_smi_wait_till_ready(dev, flash->bank, SMI_MAX_TIME_OUT);
597 if (ret) {
598 mutex_unlock(&flash->lock);
599 return ret;
600 }
601
602 mutex_lock(&dev->lock);
603 /* put smi in hw mode not wbt mode */
604 ctrlreg1 = val = readl(dev->io_base + SMI_CR1);
605 val &= ~(SW_MODE | WB_MODE);
606 if (flash->fast_mode)
607 val |= FAST_MODE;
608
609 writel(val, dev->io_base + SMI_CR1);
610
611 memcpy_fromio(buf, (u8 *)src, len);
612
613 /* restore ctrl reg1 */
614 writel(ctrlreg1, dev->io_base + SMI_CR1);
615 mutex_unlock(&dev->lock);
616
617 *retlen = len;
618 mutex_unlock(&flash->lock);
619
620 return 0;
621}
622
623static inline int spear_smi_cpy_toio(struct spear_smi *dev, u32 bank,
624 void *dest, const void *src, size_t len)
625{
626 int ret;
627 u32 ctrlreg1;
628
629 /* wait until finished previous write command. */
630 ret = spear_smi_wait_till_ready(dev, bank, SMI_MAX_TIME_OUT);
631 if (ret)
632 return ret;
633
634 /* put smi in write enable */
635 ret = spear_smi_write_enable(dev, bank);
636 if (ret)
637 return ret;
638
639 /* put smi in hw, write burst mode */
640 mutex_lock(&dev->lock);
641
642 ctrlreg1 = readl(dev->io_base + SMI_CR1);
643 writel((ctrlreg1 | WB_MODE) & ~SW_MODE, dev->io_base + SMI_CR1);
644
645 memcpy_toio(dest, src, len);
646
647 writel(ctrlreg1, dev->io_base + SMI_CR1);
648
649 mutex_unlock(&dev->lock);
650 return 0;
651}
652
653/**
654 * spear_mtd_write - performs write operation as requested by the user.
655 * @mtd: MTD information of the memory bank.
656 * @to: Address to write.
657 * @len: Number of bytes to be written.
658 * @retlen: Number of bytes actually wrote.
659 * @buf: Buffer from which the data to be taken.
660 *
661 * Write an address range to the flash chip. Data must be written in
662 * flash_page_size chunks. The address range may be any size provided
663 * it is within the physical boundaries.
664 * Returns 0 on success, non zero otherwise
665 */
666static int spear_mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
667 size_t *retlen, const u8 *buf)
668{
669 struct spear_snor_flash *flash = get_flash_data(mtd);
670 struct spear_smi *dev = mtd->priv;
671 void *dest;
672 u32 page_offset, page_size;
673 int ret;
674
675 if (!flash || !dev)
676 return -ENODEV;
677
678 if (!len)
679 return 0;
680
681 /* do not allow write past end of page */
682 if (to + len > flash->mtd.size)
683 return -EINVAL;
684
685 if (flash->bank > dev->num_flashes - 1) {
686 dev_err(&dev->pdev->dev, "Invalid Bank Num");
687 return -EINVAL;
688 }
689
690 if (!retlen)
691 return -EINVAL;
692 else
693 *retlen = 0;
694
695 /* select address as per bank number */
696 dest = flash->base_addr + to;
697 mutex_lock(&flash->lock);
698
699 page_offset = (u32)to % flash->page_size;
700
701 /* do if all the bytes fit onto one page */
702 if (page_offset + len <= flash->page_size) {
703 ret = spear_smi_cpy_toio(dev, flash->bank, dest, buf, len);
704 if (!ret)
705 *retlen += len;
706 } else {
707 u32 i;
708
709 /* the size of data remaining on the first page */
710 page_size = flash->page_size - page_offset;
711
712 ret = spear_smi_cpy_toio(dev, flash->bank, dest, buf,
713 page_size);
714 if (ret)
715 goto err_write;
716 else
717 *retlen += page_size;
718
719 /* write everything in pagesize chunks */
720 for (i = page_size; i < len; i += page_size) {
721 page_size = len - i;
722 if (page_size > flash->page_size)
723 page_size = flash->page_size;
724
725 ret = spear_smi_cpy_toio(dev, flash->bank, dest + i,
726 buf + i, page_size);
727 if (ret)
728 break;
729 else
730 *retlen += page_size;
731 }
732 }
733
734err_write:
735 mutex_unlock(&flash->lock);
736
737 return ret;
738}
739
740/**
741 * spear_smi_probe_flash - Detects the NOR Flash chip.
742 * @dev: structure of SMI information.
743 * @bank: bank on which flash must be probed
744 *
745 * This routine will check whether there exists a flash chip on a given memory
746 * bank ID.
747 * Return index of the probed flash in flash devices structure
748 */
749static int spear_smi_probe_flash(struct spear_smi *dev, u32 bank)
750{
751 int ret;
752 u32 val = 0;
753
754 ret = spear_smi_wait_till_ready(dev, bank, SMI_PROBE_TIMEOUT);
755 if (ret)
756 return ret;
757
758 mutex_lock(&dev->lock);
759
760 dev->status = 0; /* Will be set in interrupt handler */
761 /* put smi in sw mode */
762 val = readl(dev->io_base + SMI_CR1);
763 writel(val | SW_MODE, dev->io_base + SMI_CR1);
764
765 /* send readid command in sw mode */
766 writel(OPCODE_RDID, dev->io_base + SMI_TR);
767
768 val = (bank << BANK_SHIFT) | SEND | (1 << TX_LEN_SHIFT) |
769 (3 << RX_LEN_SHIFT) | TFIE;
770 writel(val, dev->io_base + SMI_CR2);
771
772 /* wait for TFF */
773 ret = wait_event_interruptible_timeout(dev->cmd_complete,
774 dev->status & TFF, SMI_CMD_TIMEOUT);
775 if (ret <= 0) {
776 ret = -ENODEV;
777 goto err_probe;
778 }
779
780 /* get memory chip id */
781 val = readl(dev->io_base + SMI_RR);
782 val &= 0x00ffffff;
783 ret = get_flash_index(val);
784
785err_probe:
786 /* clear sw mode */
787 val = readl(dev->io_base + SMI_CR1);
788 writel(val & ~SW_MODE, dev->io_base + SMI_CR1);
789
790 mutex_unlock(&dev->lock);
791 return ret;
792}
793
794static int spear_smi_setup_banks(struct platform_device *pdev, u32 bank)
795{
796 struct spear_smi *dev = platform_get_drvdata(pdev);
797 struct spear_smi_flash_info *flash_info;
798 struct spear_smi_plat_data *pdata;
799 struct spear_snor_flash *flash;
800 struct mtd_partition *parts;
801 int count;
802 int flash_index;
803 int ret = 0;
804
805 pdata = dev_get_platdata(&pdev->dev);
806 if (bank > pdata->num_flashes - 1)
807 return -EINVAL;
808
809 flash_info = &pdata->board_flash_info[bank];
810 if (!flash_info)
811 return -ENODEV;
812
813 flash = kzalloc(sizeof(*flash), GFP_ATOMIC);
814 if (!flash)
815 return -ENOMEM;
816 flash->bank = bank;
817 flash->fast_mode = flash_info->fast_mode ? 1 : 0;
818 mutex_init(&flash->lock);
819
820 /* verify whether nor flash is really present on board */
821 flash_index = spear_smi_probe_flash(dev, bank);
822 if (flash_index < 0) {
823 dev_info(&dev->pdev->dev, "smi-nor%d not found\n", bank);
824 ret = flash_index;
825 goto err_probe;
826 }
827 /* map the memory for nor flash chip */
828 flash->base_addr = ioremap(flash_info->mem_base, flash_info->size);
829 if (!flash->base_addr) {
830 ret = -EIO;
831 goto err_probe;
832 }
833
834 dev->flash[bank] = flash;
835 flash->mtd.priv = dev;
836
837 if (flash_info->name)
838 flash->mtd.name = flash_info->name;
839 else
840 flash->mtd.name = flash_devices[flash_index].name;
841
842 flash->mtd.type = MTD_NORFLASH;
843 flash->mtd.writesize = 1;
844 flash->mtd.flags = MTD_CAP_NORFLASH;
845 flash->mtd.size = flash_info->size;
846 flash->mtd.erasesize = flash_devices[flash_index].sectorsize;
847 flash->page_size = flash_devices[flash_index].pagesize;
848 flash->erase_cmd = flash_devices[flash_index].erase_cmd;
849 flash->mtd.erase = spear_mtd_erase;
850 flash->mtd.read = spear_mtd_read;
851 flash->mtd.write = spear_mtd_write;
852 flash->dev_id = flash_devices[flash_index].device_id;
853
854 dev_info(&dev->pdev->dev, "mtd .name=%s .size=%llx(%lluM)\n",
855 flash->mtd.name, flash->mtd.size,
856 flash->mtd.size / (1024 * 1024));
857
858 dev_info(&dev->pdev->dev, ".erasesize = 0x%x(%uK)\n",
859 flash->mtd.erasesize, flash->mtd.erasesize / 1024);
860
861 if (flash_info->partitions) {
862 parts = flash_info->partitions;
863 count = flash_info->nr_partitions;
864 } else {
865 /* choose from default ones */
866 switch (flash->mtd.size) {
867 case 0x800000:/* 8MB */
868 parts = part_info_8M;
869 count = ARRAY_SIZE(part_info_8M);
870 break;
871 case 0x1000000:/* 16MB */
872 parts = part_info_16M;
873 count = ARRAY_SIZE(part_info_16M);
874 break;
875 default:
876 dev_err(&pdev->dev, "undefined partition\n");
877 ret = ENODEV;
878 goto err_map;
879 }
880 }
881 ret = mtd_device_parse_register(&flash->mtd, NULL, 0, parts, count);
882 if (ret)
883 dev_err(&dev->pdev->dev, "Err MTD partition=%d\n", ret);
884
885 return ret;
886
887err_map:
888 iounmap(flash->base_addr);
889
890err_probe:
891 kfree(flash);
892 return ret;
893}
894
895/**
896 * spear_smi_probe - Entry routine
897 * @pdev: platform device structure
898 *
899 * This is the first routine which gets invoked during booting and does all
900 * initialization/allocation work. The routine looks for available memory banks,
901 * and do proper init for any found one.
902 * Returns 0 on success, non zero otherwise
903 */
904static int __devinit spear_smi_probe(struct platform_device *pdev)
905{
906 struct spear_smi_plat_data *pdata;
907 struct spear_smi *dev;
908 struct resource *smi_base;
909 int irq, ret = 0;
910 int i;
911
912 pdata = dev_get_platdata(&pdev->dev);
913 if (pdata < 0) {
914 ret = -ENODEV;
915 dev_err(&pdev->dev, "no platform data\n");
916 goto err;
917 }
918
919 smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
920 if (!smi_base) {
921 ret = -ENODEV;
922 dev_err(&pdev->dev, "invalid smi base address\n");
923 goto err;
924 }
925
926 irq = platform_get_irq(pdev, 0);
927 if (irq < 0) {
928 ret = -ENODEV;
929 dev_err(&pdev->dev, "invalid smi irq\n");
930 goto err;
931 }
932
933 dev = kzalloc(sizeof(*dev), GFP_ATOMIC);
934 if (!dev) {
935 ret = -ENOMEM;
936 dev_err(&pdev->dev, "mem alloc fail\n");
937 goto err;
938 }
939
940 smi_base = request_mem_region(smi_base->start, resource_size(smi_base),
941 pdev->name);
942 if (!smi_base) {
943 ret = -EBUSY;
944 dev_err(&pdev->dev, "request mem region fail\n");
945 goto err_mem;
946 }
947
948 dev->io_base = ioremap(smi_base->start, resource_size(smi_base));
949 if (!dev->io_base) {
950 ret = -EIO;
951 dev_err(&pdev->dev, "ioremap fail\n");
952 goto err_ioremap;
953 }
954
955 dev->pdev = pdev;
956 dev->clk_rate = pdata->clk_rate;
957
958 if (dev->clk_rate < 0 || dev->clk_rate > SMI_MAX_CLOCK_FREQ)
959 dev->clk_rate = SMI_MAX_CLOCK_FREQ;
960
961 dev->num_flashes = pdata->num_flashes;
962
963 if (dev->num_flashes > MAX_NUM_FLASH_CHIP) {
964 dev_err(&pdev->dev, "exceeding max number of flashes\n");
965 dev->num_flashes = MAX_NUM_FLASH_CHIP;
966 }
967
968 dev->clk = clk_get(&pdev->dev, NULL);
969 if (IS_ERR(dev->clk)) {
970 ret = PTR_ERR(dev->clk);
971 goto err_clk;
972 }
973
974 ret = clk_enable(dev->clk);
975 if (ret)
976 goto err_clk_enable;
977
978 ret = request_irq(irq, spear_smi_int_handler, 0, pdev->name, dev);
979 if (ret) {
980 dev_err(&dev->pdev->dev, "SMI IRQ allocation failed\n");
981 goto err_irq;
982 }
983
984 mutex_init(&dev->lock);
985 init_waitqueue_head(&dev->cmd_complete);
986 spear_smi_hw_init(dev);
987 platform_set_drvdata(pdev, dev);
988
989 /* loop for each serial nor-flash which is connected to smi */
990 for (i = 0; i < dev->num_flashes; i++) {
991 ret = spear_smi_setup_banks(pdev, i);
992 if (ret) {
993 dev_err(&dev->pdev->dev, "bank setup failed\n");
994 goto err_bank_setup;
995 }
996 }
997
998 return 0;
999
1000err_bank_setup:
1001 free_irq(irq, dev);
1002 platform_set_drvdata(pdev, NULL);
1003err_irq:
1004 clk_disable(dev->clk);
1005err_clk_enable:
1006 clk_put(dev->clk);
1007err_clk:
1008 iounmap(dev->io_base);
1009err_ioremap:
1010 release_mem_region(smi_base->start, resource_size(smi_base));
1011err_mem:
1012 kfree(dev);
1013err:
1014 return ret;
1015}
1016
1017/**
1018 * spear_smi_remove - Exit routine
1019 * @pdev: platform device structure
1020 *
1021 * free all allocations and delete the partitions.
1022 */
1023static int __devexit spear_smi_remove(struct platform_device *pdev)
1024{
1025 struct spear_smi *dev;
1026 struct spear_snor_flash *flash;
1027 int ret;
1028 int i, irq;
1029
1030 dev = platform_get_drvdata(pdev);
1031 if (!dev) {
1032 dev_err(&pdev->dev, "dev is null\n");
1033 return -ENODEV;
1034 }
1035
1036 /* clean up for all nor flash */
1037 for (i = 0; i < dev->num_flashes; i++) {
1038 flash = dev->flash[i];
1039 if (!flash)
1040 continue;
1041
1042 /* clean up mtd stuff */
1043 ret = mtd_device_unregister(&flash->mtd);
1044 if (ret)
1045 dev_err(&pdev->dev, "error removing mtd\n");
1046
1047 iounmap(flash->base_addr);
1048 kfree(flash);
1049 }
1050
1051 irq = platform_get_irq(pdev, 0);
1052 free_irq(irq, dev);
1053
1054 clk_disable(dev->clk);
1055 clk_put(dev->clk);
1056 iounmap(dev->io_base);
1057 kfree(dev);
1058 platform_set_drvdata(pdev, NULL);
1059
1060 return 0;
1061}
1062
1063int spear_smi_suspend(struct platform_device *pdev, pm_message_t state)
1064{
1065 struct spear_smi *dev = platform_get_drvdata(pdev);
1066
1067 if (dev && dev->clk)
1068 clk_disable(dev->clk);
1069
1070 return 0;
1071}
1072
1073int spear_smi_resume(struct platform_device *pdev)
1074{
1075 struct spear_smi *dev = platform_get_drvdata(pdev);
1076 int ret = -EPERM;
1077
1078 if (dev && dev->clk)
1079 ret = clk_enable(dev->clk);
1080
1081 if (!ret)
1082 spear_smi_hw_init(dev);
1083 return ret;
1084}
1085
1086static struct platform_driver spear_smi_driver = {
1087 .driver = {
1088 .name = "smi",
1089 .bus = &platform_bus_type,
1090 .owner = THIS_MODULE,
1091 },
1092 .probe = spear_smi_probe,
1093 .remove = __devexit_p(spear_smi_remove),
1094 .suspend = spear_smi_suspend,
1095 .resume = spear_smi_resume,
1096};
1097
1098static int spear_smi_init(void)
1099{
1100 return platform_driver_register(&spear_smi_driver);
1101}
1102module_init(spear_smi_init);
1103
1104static void spear_smi_exit(void)
1105{
1106 platform_driver_unregister(&spear_smi_driver);
1107}
1108module_exit(spear_smi_exit);
1109
1110MODULE_LICENSE("GPL");
1111MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim <shiraz.hashim@st.com>");
1112MODULE_DESCRIPTION("MTD SMI driver for serial nor flash chips");