jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / contrib / loaders / flash / mrvlqspi_write.S
1 /***************************************************************************
2 * Copyright (C) 2014 by Mahavir Jain <mjain@marvell.com> *
3 * *
4 * Adapted from (contrib/loaders/flash/lpcspifi_write.S): *
5 * Copyright (C) 2012 by George Harris *
6 * george@luminairecoffee.com *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
22 ***************************************************************************/
23
24 .text
25 .syntax unified
26 .cpu cortex-m3
27 .thumb
28 .thumb_func
29
30 /*
31 * For compilation:
32 * arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -c contrib/loaders/flash/mrvlqspi_write.S
33 * arm-none-eabi-objcopy -O binary mrvlqspi_write.o code.bin
34 * Copy code.bin into mrvlqspi flash driver
35 */
36
37 /*
38 * Params :
39 * r0 = workarea start, status (out)
40 * r1 = workarea end
41 * r2 = target address (offset from flash base)
42 * r3 = count (bytes)
43 * r4 = page size
44 * r5 = qspi base address
45 * Clobbered:
46 * r7 - rp
47 * r8 - wp, tmp
48 * r9 - send/receive data
49 * r10 - current page end address
50 */
51
52 #define CNTL 0x0
53 #define CONF 0x4
54 #define DOUT 0x8
55 #define DIN 0xc
56 #define INSTR 0x10
57 #define ADDR 0x14
58 #define RDMODE 0x18
59 #define HDRCNT 0x1c
60 #define DINCNT 0x20
61
62 #define SS_EN (1 << 0)
63 #define XFER_RDY (1 << 1)
64 #define RFIFO_EMPTY (1 << 4)
65 #define WFIFO_EMPTY (1 << 6)
66 #define WFIFO_FULL (1 << 7)
67 #define FIFO_FLUSH (1 << 9)
68 #define RW_EN (1 << 13)
69 #define XFER_STOP (1 << 14)
70 #define XFER_START (1 << 15)
71
72 #define INS_WRITE_ENABLE 0x06
73 #define INS_READ_STATUS 0x05
74 #define INS_PAGE_PROGRAM 0x02
75
76 init:
77 mov.w r10, #0x00
78 find_next_page_boundary:
79 add r10, r4 /* Increment to the next page */
80 cmp r10, r2
81 /* If we have not reached the next page boundary after the target address, keep going */
82 bls find_next_page_boundary
83 write_enable:
84 /* Flush read/write fifos */
85 bl flush_fifo
86
87 /* Instruction byte 1 */
88 movs r8, #0x1
89 str r8, [r5, #HDRCNT]
90
91 /* Set write enable instruction */
92 movs r8, #INS_WRITE_ENABLE
93 str r8, [r5, #INSTR]
94
95 movs r9, #0x1
96 bl start_tx
97 bl stop_tx
98 page_program:
99 /* Instruction byte 1, Addr byte 3 */
100 movs r8, #0x31
101 str r8, [r5, #HDRCNT]
102 /* Todo: set addr and data pin to single */
103 write_address:
104 mov r8, r2
105 str r8, [r5, #ADDR]
106 /* Set page program instruction */
107 movs r8, #INS_PAGE_PROGRAM
108 str r8, [r5, #INSTR]
109 /* Start write transfer */
110 movs r9, #0x1
111 bl start_tx
112 wait_fifo:
113 ldr r8, [r0] /* read the write pointer */
114 cmp r8, #0 /* if it's zero, we're gonzo */
115 beq exit
116 ldr r7, [r0, #4] /* read the read pointer */
117 cmp r7, r8 /* wait until they are not equal */
118 beq wait_fifo
119 write:
120 ldrb r9, [r7], #0x01 /* Load one byte from the FIFO, increment the read pointer by 1 */
121 bl write_data /* send the byte to the flash chip */
122
123 cmp r7, r1 /* wrap the read pointer if it is at the end */
124 it cs
125 addcs r7, r0, #8 /* skip loader args */
126 str r7, [r0, #4] /* store the new read pointer */
127 subs r3, r3, #1 /* decrement count */
128 cmp r3, #0 /* Exit if we have written everything */
129 beq write_wait
130 add r2, #1 /* Increment flash address by 1 */
131 cmp r10, r2 /* See if we have reached the end of a page */
132 bne wait_fifo /* If not, keep writing bytes */
133 write_wait:
134 bl stop_tx /* Otherwise, end the command and keep going w/ the next page */
135 add r10, r4 /* Move up the end-of-page address by the page size*/
136 check_flash_busy: /* Wait for the flash to finish the previous page write */
137 /* Flush read/write fifos */
138 bl flush_fifo
139 /* Instruction byte 1 */
140 movs r8, #0x1
141 str r8, [r5, #HDRCNT]
142 /* Continuous data in of status register */
143 movs r8, #0x0
144 str r8, [r5, #DINCNT]
145 /* Set write enable instruction */
146 movs r8, #INS_READ_STATUS
147 str r8, [r5, #INSTR]
148 /* Start read transfer */
149 movs r9, #0x0
150 bl start_tx
151 wait_flash_busy:
152 bl read_data
153 and.w r9, r9, #0x1
154 cmp r9, #0x0
155 bne.n wait_flash_busy
156 bl stop_tx
157 cmp r3, #0
158 bne.n write_enable /* If it is done, start a new page write */
159 b exit /* All data written, exit */
160
161 write_data: /* Send/receive 1 byte of data over QSPI */
162 ldr r8, [r5, #CNTL]
163 lsls r8, r8, #24
164 bmi.n write_data
165 str r9, [r5, #DOUT]
166 bx lr
167
168 read_data: /* Read 1 byte of data over QSPI */
169 ldr r8, [r5, #CNTL]
170 lsls r8, r8, #27
171 bmi.n read_data
172 ldr r9, [r5, #DIN]
173 bx lr
174
175 flush_fifo: /* Flush read write fifos */
176 ldr r8, [r5, #CONF]
177 orr.w r8, r8, #FIFO_FLUSH
178 str r8, [r5, #CONF]
179 flush_reset:
180 ldr r8, [r5, #CONF]
181 lsls r8, r8, #22
182 bmi.n flush_reset
183 bx lr
184
185 start_tx:
186 ldr r8, [r5, #CNTL]
187 orr.w r8, r8, #SS_EN
188 str r8, [r5, #CNTL]
189 xfer_rdy:
190 ldr r8, [r5, #CNTL]
191 lsls r8, r8, #30
192 bpl.n xfer_rdy
193 ldr r8, [r5, #CONF]
194 bfi r8, r9, #13, #1
195 orr.w r8, r8, #XFER_START
196 str r8, [r5, #CONF]
197 bx lr
198
199 stop_tx:
200 ldr r8, [r5, #CNTL]
201 lsls r8, r8, #30
202 bpl.n stop_tx
203 wfifo_wait:
204 ldr r8, [r5, #CNTL]
205 lsls r8, r8, #25
206 bpl.n wfifo_wait
207 ldr r8, [r5, #CONF]
208 orr.w r8, r8, #XFER_STOP
209 str r8, [r5, #CONF]
210 xfer_start:
211 ldr r8, [r5, #CONF]
212 lsls r8, r8, #16
213 bmi.n xfer_start
214 ss_disable:
215 # Disable SS_EN
216 ldr r8, [r5, #CNTL]
217 bic.w r8, r8, #SS_EN
218 str r8, [r5, #CNTL]
219 wait:
220 ldr r8, [r5, #CNTL]
221 lsls r8, r8, #30
222 bpl.n wait
223 bx lr
224
225 error:
226 movs r0, #0
227 str r0, [r2, #4] /* set rp = 0 on error */
228 exit:
229 mov r0, r6
230 bkpt #0x00
231
232 .end

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)