diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/devices/st_spi_fsm.c | 95 |
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 */ | ||
667 | static 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 | |||
666 | static int stfsm_n25q_en_32bit_addr_seq(struct stfsm_seq *seq) | 683 | static 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 | ||
698 | static 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 | |||
714 | static inline void stfsm_load_seq(struct stfsm *fsm, | 715 | static 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 | */ | ||
802 | static 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 | |||
775 | static int stfsm_write_fifo(struct stfsm *fsm, const uint32_t *buf, | 838 | static int stfsm_write_fifo(struct stfsm *fsm, const uint32_t *buf, |
776 | uint32_t size) | 839 | uint32_t size) |
777 | { | 840 | { |