diff options
| author | Shiraz Hashim <shiraz.hashim@st.com> | 2012-01-12 08:38:57 -0500 |
|---|---|---|
| committer | David Woodhouse <David.Woodhouse@intel.com> | 2012-03-26 19:14:16 -0400 |
| commit | f18dbbb1bfe06ea3995b55c2f533057da9e9294a (patch) | |
| tree | 03977f824b653bdaff5638429b6f6bd84577da4e | |
| parent | 661a08327d11bcc4cf649c5ae4bdf2db0a87b320 (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>
| -rw-r--r-- | drivers/mtd/devices/Kconfig | 7 | ||||
| -rw-r--r-- | drivers/mtd/devices/Makefile | 1 | ||||
| -rw-r--r-- | drivers/mtd/devices/spear_smi.c | 1112 | ||||
| -rw-r--r-- | include/linux/mtd/spear_smi.h | 60 |
4 files changed, 1180 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 | ||
| 105 | config 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 | |||
| 105 | config MTD_SST25L | 112 | config 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 | |||
| 17 | obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o | 17 | obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o |
| 18 | obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o | 18 | obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o |
| 19 | obj-$(CONFIG_MTD_M25P80) += m25p80.o | 19 | obj-$(CONFIG_MTD_M25P80) += m25p80.o |
| 20 | obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o | ||
| 20 | obj-$(CONFIG_MTD_SST25L) += sst25l.o | 21 | obj-$(CONFIG_MTD_SST25L) += sst25l.o |
| 21 | 22 | ||
| 22 | CFLAGS_docg3.o += -I$(src) \ No newline at end of file | 23 | CFLAGS_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 */ | ||
| 96 | struct 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 | |||
| 115 | static 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), | ||
