aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorLee Jones <lee.jones@linaro.org>2014-03-20 05:20:57 -0400
committerBrian Norris <computersforpeace@gmail.com>2014-03-20 07:17:19 -0400
commite514f10578ede5b5b07213cfebb57a2907e13f65 (patch)
tree39d768a661d5f80270292c23cdfd45be646c06ff /drivers/mtd
parent4eb3f0d8f70b667f8a59cc4f74003884562ef17f (diff)
mtd: st_spi_fsm: Add the ability to read from a Serial Flash device
When a read is issued by userspace the MTD framework calls back into the driver to conduct the actual command issue and data extraction. Here we provide the routines which do exactly that. Acked-by Angus Clark <angus.clark@st.com> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/devices/st_spi_fsm.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index b4afee0e0e33..b1a65c1359d5 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -238,6 +238,9 @@
238#define FLASH_CMD_READ4_1_1_4 0x6c 238#define FLASH_CMD_READ4_1_1_4 0x6c
239#define FLASH_CMD_READ4_1_4_4 0xec 239#define FLASH_CMD_READ4_1_4_4 0xec
240 240
241#define FLASH_PAGESIZE 256 /* In Bytes */
242#define FLASH_PAGESIZE_32 (FLASH_PAGESIZE / 4) /* In uint32_t */
243
241/* 244/*
242 * Flags to tweak operation of default read/write/erase routines 245 * Flags to tweak operation of default read/write/erase routines
243 */ 246 */
@@ -942,6 +945,99 @@ static int stfsm_n25q_config(struct stfsm *fsm)
942 return 0; 945 return 0;
943} 946}
944 947
948static int stfsm_read(struct stfsm *fsm, uint8_t *buf, uint32_t size,
949 uint32_t offset)
950{
951 struct stfsm_seq *seq = &stfsm_seq_read;
952 uint32_t data_pads;
953 uint32_t read_mask;
954 uint32_t size_ub;
955 uint32_t size_lb;
956 uint32_t size_mop;
957 uint32_t tmp[4];
958 uint32_t page_buf[FLASH_PAGESIZE_32];
959 uint8_t *p;
960
961 dev_dbg(fsm->dev, "reading %d bytes from 0x%08x\n", size, offset);
962
963 /* Enter 32-bit address mode, if required */
964 if (fsm->configuration & CFG_READ_TOGGLE_32BIT_ADDR)
965 stfsm_enter_32bit_addr(fsm, 1);
966
967 /* Must read in multiples of 32 cycles (or 32*pads/8 Bytes) */
968 data_pads = ((seq->seq_cfg >> 16) & 0x3) + 1;
969 read_mask = (data_pads << 2) - 1;
970
971 /* Handle non-aligned buf */
972 p = ((uint32_t)buf & 0x3) ? (uint8_t *)page_buf : buf;
973
974 /* Handle non-aligned size */
975 size_ub = (size + read_mask) & ~read_mask;
976 size_lb = size & ~read_mask;
977 size_mop = size & read_mask;
978
979 seq->data_size = TRANSFER_SIZE(size_ub);
980 seq->addr1 = (offset >> 16) & 0xffff;
981 seq->addr2 = offset & 0xffff;
982
983 stfsm_load_seq(fsm, seq);
984
985 if (size_lb)
986 stfsm_read_fifo(fsm, (uint32_t *)p, size_lb);
987
988 if (size_mop) {
989 stfsm_read_fifo(fsm, tmp, read_mask + 1);
990 memcpy(p + size_lb, &tmp, size_mop);
991 }
992
993 /* Handle non-aligned buf */
994 if ((uint32_t)buf & 0x3)
995 memcpy(buf, page_buf, size);
996
997 /* Wait for sequence to finish */
998 stfsm_wait_seq(fsm);
999
1000 stfsm_clear_fifo(fsm);
1001
1002 /* Exit 32-bit address mode, if required */
1003 if (fsm->configuration & CFG_READ_TOGGLE_32BIT_ADDR)
1004 stfsm_enter_32bit_addr(fsm, 0);
1005
1006 return 0;
1007}
1008
1009/*
1010 * Read an address range from the flash chip. The address range
1011 * may be any size provided it is within the physical boundaries.
1012 */
1013static int stfsm_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
1014 size_t *retlen, u_char *buf)
1015{
1016 struct stfsm *fsm = dev_get_drvdata(mtd->dev.parent);
1017 uint32_t bytes;
1018
1019 dev_dbg(fsm->dev, "%s from 0x%08x, len %zd\n",
1020 __func__, (u32)from, len);
1021
1022 mutex_lock(&fsm->lock);
1023
1024 while (len > 0) {
1025 bytes = min_t(size_t, len, FLASH_PAGESIZE);
1026
1027 stfsm_read(fsm, buf, bytes, from);
1028
1029 buf += bytes;
1030 from += bytes;
1031 len -= bytes;
1032
1033 *retlen += bytes;
1034 }
1035
1036 mutex_unlock(&fsm->lock);
1037
1038 return 0;
1039}
1040
945static void stfsm_read_jedec(struct stfsm *fsm, uint8_t *const jedec) 1041static void stfsm_read_jedec(struct stfsm *fsm, uint8_t *const jedec)
946{ 1042{
947 const struct stfsm_seq *seq = &stfsm_seq_read_jedec; 1043 const struct stfsm_seq *seq = &stfsm_seq_read_jedec;
@@ -1197,6 +1293,8 @@ static int stfsm_probe(struct platform_device *pdev)
1197 fsm->mtd.size = info->sector_size * info->n_sectors; 1293 fsm->mtd.size = info->sector_size * info->n_sectors;
1198 fsm->mtd.erasesize = info->sector_size; 1294 fsm->mtd.erasesize = info->sector_size;
1199 1295
1296 fsm->mtd._read = stfsm_mtd_read;
1297
1200 dev_err(&pdev->dev, 1298 dev_err(&pdev->dev,
1201 "Found serial flash device: %s\n" 1299 "Found serial flash device: %s\n"
1202 " size = %llx (%lldMiB) erasesize = 0x%08x (%uKiB)\n", 1300 " size = %llx (%lldMiB) erasesize = 0x%08x (%uKiB)\n",