aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLee Jones <lee.jones@linaro.org>2014-03-20 05:20:55 -0400
committerBrian Norris <computersforpeace@gmail.com>2014-03-20 07:17:18 -0400
commit218b870f906b609d37737ee176dc4fcba86163d4 (patch)
tree08d6aa895d091bb0603517b438dbbde6eb113c9a
parente85a619676a503d7622c17d38c2cc9f26b59f2be (diff)
mtd: st_spi_fsm: Supply the N25Qxxx chip specific configuration call-back
In the FSM driver we handle chip differences by providing the possibility of calling back into a chip specific initialisation routine. In this patch we provide one for the N25Qxxx series, which endeavours to setup things like the read, write and erase sequences, as they differ from the default. We also configure 32bit support and the amount of dummy cycles to use. 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>
-rw-r--r--drivers/mtd/devices/st_spi_fsm.c84
1 files changed, 82 insertions, 2 deletions
diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index c902d5bc69a4..b4d2a188672e 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -312,6 +312,8 @@ struct flash_info {
312 int (*config)(struct stfsm *); 312 int (*config)(struct stfsm *);
313}; 313};
314 314
315static int stfsm_n25q_config(struct stfsm *fsm);
316
315static struct flash_info flash_types[] = { 317static struct flash_info flash_types[] = {
316 /* 318 /*
317 * ST Microelectronics/Numonyx -- 319 * ST Microelectronics/Numonyx --
@@ -354,9 +356,10 @@ static struct flash_info flash_types[] = {
354 FLASH_FLAG_WRITE_1_2_2 | \ 356 FLASH_FLAG_WRITE_1_2_2 | \
355 FLASH_FLAG_WRITE_1_1_4 | \ 357 FLASH_FLAG_WRITE_1_1_4 | \
356 FLASH_FLAG_WRITE_1_4_4) 358 FLASH_FLAG_WRITE_1_4_4)
357 { "n25q128", 0x20ba18, 0, 64 * 1024, 256, N25Q_FLAG, 108, NULL }, 359 { "n25q128", 0x20ba18, 0, 64 * 1024, 256, N25Q_FLAG, 108,
360 stfsm_n25q_config },
358 { "n25q256", 0x20ba19, 0, 64 * 1024, 512, 361 { "n25q256", 0x20ba19, 0, 64 * 1024, 512,
359 N25Q_FLAG | FLASH_FLAG_32BIT_ADDR, 108, NULL }, 362 N25Q_FLAG | FLASH_FLAG_32BIT_ADDR, 108, stfsm_n25q_config },
360 363
361 /* 364 /*
362 * Spansion S25FLxxxP 365 * Spansion S25FLxxxP
@@ -493,6 +496,8 @@ static struct seq_rw_config n25q_read4_configs[] = {
493 {0x00, 0, 0, 0, 0, 0x00, 0, 0}, 496 {0x00, 0, 0, 0, 0, 0x00, 0, 0},
494}; 497};
495 498
499static struct stfsm_seq stfsm_seq_read; /* Dynamically populated */
500static struct stfsm_seq stfsm_seq_write; /* Dynamically populated */
496static struct stfsm_seq stfsm_seq_en_32bit_addr;/* Dynamically populated */ 501static struct stfsm_seq stfsm_seq_en_32bit_addr;/* Dynamically populated */
497 502
498static struct stfsm_seq stfsm_seq_read_jedec = { 503static struct stfsm_seq stfsm_seq_read_jedec = {
@@ -840,6 +845,71 @@ static int stfsm_search_prepare_rw_seq(struct stfsm *fsm,
840 return 0; 845 return 0;
841} 846}
842 847
848static int stfsm_n25q_config(struct stfsm *fsm)
849{
850 uint32_t flags = fsm->info->flags;
851 uint8_t vcr;
852 int ret = 0;
853 bool soc_reset;
854
855 /* Configure 'READ' sequence */
856 if (flags & FLASH_FLAG_32BIT_ADDR)
857 ret = stfsm_search_prepare_rw_seq(fsm, &stfsm_seq_read,
858 n25q_read4_configs);
859 else
860 ret = stfsm_search_prepare_rw_seq(fsm, &stfsm_seq_read,
861 n25q_read3_configs);
862 if (ret) {
863 dev_err(fsm->dev,
864 "failed to prepare READ sequence with flags [0x%08x]\n",
865 flags);
866 return ret;
867 }
868
869 /* Configure 'WRITE' sequence (default configs) */
870 ret = stfsm_search_prepare_rw_seq(fsm, &stfsm_seq_write,
871 default_write_configs);
872 if (ret) {
873 dev_err(fsm->dev,
874 "preparing WRITE sequence using flags [0x%08x] failed\n",
875 flags);
876 return ret;
877 }
878
879 /* * Configure 'ERASE_SECTOR' sequence */
880 stfsm_prepare_erasesec_seq(fsm, &stfsm_seq_erase_sector);
881
882 /* Configure 32-bit address support */
883 if (flags & FLASH_FLAG_32BIT_ADDR) {
884 stfsm_n25q_en_32bit_addr_seq(&stfsm_seq_en_32bit_addr);
885
886 soc_reset = stfsm_can_handle_soc_reset(fsm);
887 if (soc_reset || !fsm->booted_from_spi) {
888 /*
889 * If we can handle SoC resets, we enable 32-bit
890 * address mode pervasively
891 */
892 stfsm_enter_32bit_addr(fsm, 1);
893 } else {
894 /*
895 * If not, enable/disable for WRITE and ERASE
896 * operations (READ uses special commands)
897 */
898 fsm->configuration = (CFG_WRITE_TOGGLE_32BIT_ADDR |
899 CFG_ERASESEC_TOGGLE_32BIT_ADDR);
900 }
901 }
902
903 /*
904 * Configure device to use 8 dummy cycles
905 */
906 vcr = (N25Q_VCR_DUMMY_CYCLES(8) | N25Q_VCR_XIP_DISABLED |
907 N25Q_VCR_WRAP_CONT);
908 stfsm_wrvcr(fsm, vcr);
909
910 return 0;
911}
912
843static void stfsm_read_jedec(struct stfsm *fsm, uint8_t *const jedec) 913static void stfsm_read_jedec(struct stfsm *fsm, uint8_t *const jedec)
844{ 914{
845 const struct stfsm_seq *seq = &stfsm_seq_read_jedec; 915 const struct stfsm_seq *seq = &stfsm_seq_read_jedec;
@@ -1073,6 +1143,16 @@ static int stfsm_probe(struct platform_device *pdev)
1073 if (info->sector_size * info->n_sectors > 0x1000000) 1143 if (info->sector_size * info->n_sectors > 0x1000000)
1074 info->flags |= FLASH_FLAG_32BIT_ADDR; 1144 info->flags |= FLASH_FLAG_32BIT_ADDR;
1075 1145
1146 /*
1147 * Configure READ/WRITE/ERASE sequences according to platform and
1148 * device flags.
1149 */
1150 if (info->config) {
1151 ret = info->config(fsm);
1152 if (ret)
1153 return ret;
1154 }
1155
1076 fsm->mtd.dev.parent = &pdev->dev; 1156 fsm->mtd.dev.parent = &pdev->dev;
1077 fsm->mtd.type = MTD_NORFLASH; 1157 fsm->mtd.type = MTD_NORFLASH;
1078 fsm->mtd.writesize = 4; 1158 fsm->mtd.writesize = 4;