1 /* SPDX-License-Identifier: GPL-2.0+ */
3 * SH QSPI (Quad SPI) driver
4 * Copyright (C) 2019 Marek Vasut <marek.vasut@gmail.com>
7 #define BIT(n) (1UL << (n))
8 /* SH QSPI register bit masks <REG>_<BIT> */
11 #define SPSR_SPRFF 0x80
12 #define SPSR_SPTEF 0x20
13 #define SPPCR_IO3FV 0x04
14 #define SPPCR_IO2FV 0x02
15 #define SPPCR_IO1FV 0x01
16 #define SPBDCR_RXBC0 BIT(0)
17 #define SPCMD_SCKDEN BIT(15)
18 #define SPCMD_SLNDEN BIT(14)
19 #define SPCMD_SPNDEN BIT(13)
20 #define SPCMD_SSLKP BIT(7)
21 #define SPCMD_BRDV0 BIT(2)
22 #define SPCMD_INIT1 SPCMD_SCKDEN | SPCMD_SLNDEN | \
23 SPCMD_SPNDEN | SPCMD_SSLKP | \
25 #define SPCMD_INIT2 SPCMD_SPNDEN | SPCMD_SSLKP | \
27 #define SPBFCR_TXRST BIT(7)
28 #define SPBFCR_RXRST BIT(6)
29 #define SPBFCR_TXTRG 0x30
30 #define SPBFCR_RXTRG 0x07
32 /* SH QSPI register set */
33 #define SH_QSPI_SPCR 0x00
34 #define SH_QSPI_SSLP 0x01
35 #define SH_QSPI_SPPCR 0x02
36 #define SH_QSPI_SPSR 0x03
37 #define SH_QSPI_SPDR 0x04
38 #define SH_QSPI_SPSCR 0x08
39 #define SH_QSPI_SPSSR 0x09
40 #define SH_QSPI_SPBR 0x0a
41 #define SH_QSPI_SPDCR 0x0b
42 #define SH_QSPI_SPCKD 0x0c
43 #define SH_QSPI_SSLND 0x0d
44 #define SH_QSPI_SPND 0x0e
45 #define SH_QSPI_DUMMY0 0x0f
46 #define SH_QSPI_SPCMD0 0x10
47 #define SH_QSPI_SPCMD1 0x12
48 #define SH_QSPI_SPCMD2 0x14
49 #define SH_QSPI_SPCMD3 0x16
50 #define SH_QSPI_SPBFCR 0x18
51 #define SH_QSPI_DUMMY1 0x19
52 #define SH_QSPI_SPBDCR 0x1a
53 #define SH_QSPI_SPBMUL0 0x1c
54 #define SH_QSPI_SPBMUL1 0x20
55 #define SH_QSPI_SPBMUL2 0x24
56 #define SH_QSPI_SPBMUL3 0x28
62 .macro wait_for_spsr, spsrbit
63 1: ldrb r12, [r0, #SH_QSPI_SPSR]
69 bl sh_qspi_cs_activate
70 str r6, [r0, SH_QSPI_SPBMUL0]
71 bl sh_qspi_xfer_common
72 bl sh_qspi_cs_deactivate
75 .macro sh_qspi_write_enable
76 ldr r4, =SPIFLASH_WRITE_ENABLE
84 .macro sh_qspi_wait_till_ready
85 1: ldr r4, =SPIFLASH_READ_STATUS
97 * r0: controller base address
98 * r1: data buffer base address
99 * r2: BIT(31) -- page program (not read)
100 * BIT(30) -- 4-byte address (not 3-byte)
101 * BIT(29) -- 512-byte page (not 256-byte)
102 * BIT(27:20) -- SF command
103 * BIT(19:0) -- amount of data to read/write
104 * r3: SF target address
109 * r14: lr, link register
110 * r15: pc, program counter
112 * Clobber: r4, r5, r6, r7, r8
117 bic r7, r2, #0xff000000
118 bic r7, r7, #0x00f00000
120 and r8, r2, #(1 << 31)
126 bl sh_qspi_cs_activate
128 bl sh_qspi_setup_command
130 str r8, [r0, SH_QSPI_SPBMUL0]
131 bl sh_qspi_xfer_common
136 bl sh_qspi_xfer_common
138 bl sh_qspi_cs_deactivate
149 /* Check if less then page bytes left. */
155 bl sh_qspi_cs_activate
157 bl sh_qspi_setup_command
158 str r6, [r0, SH_QSPI_SPBMUL0]
159 bl sh_qspi_xfer_common
165 bl sh_qspi_xfer_common
167 bl sh_qspi_cs_deactivate
169 sh_qspi_wait_till_ready
182 /* Set master mode only */
184 strb r12, [r0, SH_QSPI_SPCR]
187 mov r12, #SPCMD_INIT1
188 strh r12, [r0, SH_QSPI_SPCMD0]
190 /* Reset transfer and receive Buffer */
191 ldrb r12, [r0, SH_QSPI_SPSCR]
192 orr r12, #(SPBFCR_TXRST | SPBFCR_RXRST)
193 strb r12, [r0, SH_QSPI_SPBFCR]
195 /* Clear transfer and receive Buffer control bit */
196 ldrb r12, [r0, SH_QSPI_SPBFCR]
197 bic r12, #(SPBFCR_TXRST | SPBFCR_RXRST)
198 strb r12, [r0, SH_QSPI_SPBFCR]
200 /* Set sequence control method. Use sequence0 only */
202 strb r12, [r0, SH_QSPI_SPSCR]
204 /* Enable SPI function */
205 ldrb r12, [r0, SH_QSPI_SPCR]
207 strb r12, [r0, SH_QSPI_SPCR]
211 sh_qspi_cs_deactivate:
212 /* Disable SPI function */
213 ldrb r12, [r0, SH_QSPI_SPCR]
215 strb r12, [r0, SH_QSPI_SPCR]
220 * r0, controller base address
223 * r6, xfer len, non-zero
225 * Upon exit, r13 contains the last byte in SPDR
227 * Clobber: r11, r12, r13
231 ldr r13, [r0, #SH_QSPI_SPBFCR]
232 orr r13, #(SPBFCR_TXTRG | SPBFCR_RXTRG)
236 biclt r13, #(SPBFCR_TXTRG | SPBFCR_RXTRG)
240 str r13, [r0, #SH_QSPI_SPBFCR]
242 wait_for_spsr SPSR_SPTEF
249 2: ldrb r13, [r4], #1
250 strb r13, [r0, #SH_QSPI_SPDR]
255 3: strb r13, [r0, #SH_QSPI_SPDR]
259 4: wait_for_spsr SPSR_SPRFF
265 5: ldrb r13, [r0, #SH_QSPI_SPDR]
271 6: ldrb r13, [r0, #SH_QSPI_SPDR]
280 sh_qspi_setup_command:
281 ldr r4, =SPIFLASH_SCRATCH_DATA
284 and r12, r2, #0x0ff00000
303 SPIFLASH_READ_STATUS: .byte 0x05 /* Read Status Register */
304 SPIFLASH_WRITE_ENABLE: .byte 0x06 /* Write Enable */
305 SPIFLASH_NOOP: .byte 0x00
306 SPIFLASH_SCRATCH_DATA: .byte 0x00, 0x0, 0x0, 0x0, 0x0