aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorLee Jones <lee.jones@linaro.org>2014-12-15 06:59:08 -0500
committerBrian Norris <computersforpeace@gmail.com>2015-01-13 00:08:00 -0500
commit5ecd3ea188fd60e5f663a956dbe23d61a99f504a (patch)
tree2cbce2b9b91902608cefa53a2df5fce52ef86644 /drivers/mtd
parente4999bbe0802ddff82b3fcbbab3b6274b789aad7 (diff)
mtd: st_spi_fsm: Extend fsm_clear_fifo to handle unwanted bytes
Under certain conditions, the SPI-FSM Controller can be left in a state where the data FIFO is not entirely empty. This can lead to problems where subsequent data transfers appear to have been shifted by a number of unidentified bytes. One simple example would be an errant FSM sequence which loaded more data to the FIFO than was read by the host. Another more interesting case results from an obscure artefact in the FSM Controller. When switching from data transfers in x4 or x2 mode to data transfers in x1 mode, extraneous bytes will appear in the FIFO, unless the previous data transfer was a multiple of 32 cycles (i.e. 8 bytes for x2, and 16 bytes for x4). This applies equally whether FSM is being operated directly by a S/W driver, or by the SPI boot-controller in FSM-Boot mode. Furthermore, data in the FIFO not only survive a transition between FSM-Boot and FSM, but also a S/W reset of IP block [1]. By taking certain precautions, it is possible to prevent the driver from causing this type of problem (e.g. ensuring that the host and programmed sequence agree on the transfer size, and restricting transfer sizes to multiples of 32-cycles [2]). However, at the point the driver is loaded, no assumptions can be made regarding the state of the FIFO. Even if previous S/W drivers have behaved correctly, it is impossible to control the number of transactions serviced by the controller operating in FSM-Boot. To address this problem, we ensure the FIFO is cleared during initialisation, before performing any FSM operations. Previously, the fsm_clear_fifo() code was capable of detecting and clearing any unwanted 32-bit words from the FIFO. This patch extends the capability to handle an arbitrary number of bytes present in the FIFO [3]. Now that the issue is better understood, we also remove the calls to fsm_clear_fifo() following the fsm_read() and fsm_write() operations. The process of actually clearing the FIFO deserves a mention. While the FIFO may contain any number of bytes, the SPI_FAST_SEQ_STA register only reports the number of complete 32-bit words present. Furthermore, data can only be drained from the FIFO by reading complete 32-bit words. With this in mind, a two stage process is used to the clear the FIFO: 1. Read any complete 32-bit words from the FIFO, as reported by the SPI_FAST_SEQ_STA register. 2. Mop up any remaining bytes. At this point, it is not known if there are 0, 1, 2, or 3 bytes in the FIFO. To handle all cases, a dummy FSM sequence is used to load one byte at a time, until a complete 32-bit word is formed; at most, 4 bytes will need to be loaded. [1] Although this issue has existed since early versions of the SPI-FSM controller, its full extent only emerged recently as a consequence of the targetpacks starting to use FSM-Boot(x4) as the default configuration. [2] The requirement to restrict transfers to multiples of 32 cycles was found empirically back when DUAL and QUAD mode support was added. The current analysis now gives a satisfactory explanation for this requirement. [3] Theoretically, it is possible for the FIFO to contain an arbitrary number of bits. However, since there are no known use-cases that leave incomplete bytes in the FIFO, only words and bytes are considered here. Signed-off-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.c95
1 files changed, 79 insertions, 16 deletions
diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 54ffe5223e64..bebc8b5637c0 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -663,6 +663,23 @@ static struct stfsm_seq stfsm_seq_write_status = {
663 SEQ_CFG_STARTSEQ), 663 SEQ_CFG_STARTSEQ),
664}; 664};
665 665
666/* Dummy sequence to read one byte of data from flash into the FIFO */
667static const struct stfsm_seq stfsm_seq_load_fifo_byte = {
668 .data_size = TRANSFER_SIZE(1),
669 .seq_opc[0] = (SEQ_OPC_PADS_1 |
670 SEQ_OPC_CYCLES(8) |
671 SEQ_OPC_OPCODE(SPINOR_OP_RDID)),
672 .seq = {
673 STFSM_INST_CMD1,
674 STFSM_INST_DATA_READ,
675 STFSM_INST_STOP,
676 },
677 .seq_cfg = (SEQ_CFG_PADS_1 |
678 SEQ_CFG_READNOTWRITE |
679 SEQ_CFG_CSDEASSERT |
680 SEQ_CFG_STARTSEQ),
681};
682
666static int stfsm_n25q_en_32bit_addr_seq(struct stfsm_seq *seq) 683static int stfsm_n25q_en_32bit_addr_seq(struct stfsm_seq *seq)
667{ 684{
668 seq->seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) | 685 seq->seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
@@ -695,22 +712,6 @@ static inline uint32_t stfsm_fifo_available(struct stfsm *fsm)
695 return (readl(fsm->base + SPI_FAST_SEQ_STA) >> 5) & 0x7f; 712 return (readl(fsm->base + SPI_FAST_SEQ_STA) >> 5) & 0x7f;
696} 713}
697 714
698static void stfsm_clear_fifo(struct stfsm *fsm)
699{
700 uint32_t avail;
701
702 for (;;) {
703 avail = stfsm_fifo_available(fsm);
704 if (!avail)
705 break;
706
707 while (avail) {
708 readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
709 avail--;
710 }
711 }
712}
713
714static inline void stfsm_load_seq(struct stfsm *fsm, 715static inline void stfsm_load_seq(struct stfsm *fsm,
715 const struct stfsm_seq *seq) 716 const struct stfsm_seq *seq)
716{ 717{
@@ -772,6 +773,68 @@ static void stfsm_read_fifo(struct stfsm *fsm, uint32_t *buf, uint32_t size)
772 } 773 }
773} 774}
774 775
776/*
777 * Clear the data FIFO
778 *
779 * Typically, this is only required during driver initialisation, where no
780 * assumptions can be made regarding the state of the FIFO.
781 *
782 * The process of clearing the FIFO is complicated by fact that while it is
783 * possible for the FIFO to contain an arbitrary number of bytes [1], the
784 * SPI_FAST_SEQ_STA register only reports the number of complete 32-bit words
785 * present. Furthermore, data can only be drained from the FIFO by reading
786 * complete 32-bit words.
787 *
788 * With this in mind, a two stage process is used to the clear the FIFO:
789 *
790 * 1. Read any complete 32-bit words from the FIFO, as reported by the
791 * SPI_FAST_SEQ_STA register.
792 *
793 * 2. Mop up any remaining bytes. At this point, it is not known if there
794 * are 0, 1, 2, or 3 bytes in the FIFO. To handle all cases, a dummy FSM
795 * sequence is used to load one byte at a time, until a complete 32-bit
796 * word is formed; at most, 4 bytes will need to be loaded.
797 *
798 * [1] It is theoretically possible for the FIFO to contain an arbitrary number
799 * of bits. However, since there are no known use-cases that leave
800 * incomplete bytes in the FIFO, only words and bytes are considered here.
801 */
802static void stfsm_clear_fifo(struct stfsm *fsm)
803{
804 const struct stfsm_seq *seq = &stfsm_seq_load_fifo_byte;
805 uint32_t words, i;
806
807 /* 1. Clear any 32-bit words */
808 words = stfsm_fifo_available(fsm);
809 if (words) {
810 for (i = 0; i < words; i++)
811 readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
812 dev_dbg(fsm->dev, "cleared %d words from FIFO\n", words);
813 }
814
815 /*
816 * 2. Clear any remaining bytes
817 * - Load the FIFO, one byte at a time, until a complete 32-bit word
818 * is available.
819 */
820 for (i = 0, words = 0; i < 4 && !words; i++) {
821 stfsm_load_seq(fsm, seq);
822 stfsm_wait_seq(fsm);
823 words = stfsm_fifo_available(fsm);
824 }
825
826 /* - A single word must be available now */
827 if (words != 1) {
828 dev_err(fsm->dev, "failed to clear bytes from the data FIFO\n");
829 return;
830 }
831
832 /* - Read the 32-bit word */
833 readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
834
835 dev_dbg(fsm->dev, "cleared %d byte(s) from the data FIFO\n", 4 - i);
836}
837
775static int stfsm_write_fifo(struct stfsm *fsm, const uint32_t *buf, 838static int stfsm_write_fifo(struct stfsm *fsm, const uint32_t *buf,
776 uint32_t size) 839 uint32_t size)
777{ 840{