Commit ab92224f4550f9677be32dd903e99acf1475dbf7

Authored by Jagannadha Sutradharudu Teki
1 parent 2ba863fae6

sf: ops: Unify read_ops bank configuration

Unified the bar code from read_ops into a spi_flash_bar()

Signed-off-by: Jagannadha Sutradharudu Teki <jaganna@xilinx.com>

Showing 1 changed file with 5 additions and 8 deletions Inline Diff

drivers/mtd/spi/sf_ops.c
1 /* 1 /*
2 * SPI flash operations 2 * SPI flash operations
3 * 3 *
4 * Copyright (C) 2008 Atmel Corporation 4 * Copyright (C) 2008 Atmel Corporation
5 * Copyright (C) 2010 Reinhard Meyer, EMK Elektronik 5 * Copyright (C) 2010 Reinhard Meyer, EMK Elektronik
6 * Copyright (C) 2013 Jagannadha Sutradharudu Teki, Xilinx Inc. 6 * Copyright (C) 2013 Jagannadha Sutradharudu Teki, Xilinx Inc.
7 * 7 *
8 * SPDX-License-Identifier: GPL-2.0+ 8 * SPDX-License-Identifier: GPL-2.0+
9 */ 9 */
10 10
11 #include <common.h> 11 #include <common.h>
12 #include <malloc.h> 12 #include <malloc.h>
13 #include <spi.h> 13 #include <spi.h>
14 #include <spi_flash.h> 14 #include <spi_flash.h>
15 #include <watchdog.h> 15 #include <watchdog.h>
16 16
17 #include "sf_internal.h" 17 #include "sf_internal.h"
18 18
19 static void spi_flash_addr(u32 addr, u8 *cmd) 19 static void spi_flash_addr(u32 addr, u8 *cmd)
20 { 20 {
21 /* cmd[0] is actual command */ 21 /* cmd[0] is actual command */
22 cmd[1] = addr >> 16; 22 cmd[1] = addr >> 16;
23 cmd[2] = addr >> 8; 23 cmd[2] = addr >> 8;
24 cmd[3] = addr >> 0; 24 cmd[3] = addr >> 0;
25 } 25 }
26 26
27 int spi_flash_cmd_read_status(struct spi_flash *flash, u8 *rs) 27 int spi_flash_cmd_read_status(struct spi_flash *flash, u8 *rs)
28 { 28 {
29 int ret; 29 int ret;
30 u8 cmd; 30 u8 cmd;
31 31
32 cmd = CMD_READ_STATUS; 32 cmd = CMD_READ_STATUS;
33 ret = spi_flash_read_common(flash, &cmd, 1, rs, 1); 33 ret = spi_flash_read_common(flash, &cmd, 1, rs, 1);
34 if (ret < 0) { 34 if (ret < 0) {
35 debug("SF: fail to read status register\n"); 35 debug("SF: fail to read status register\n");
36 return ret; 36 return ret;
37 } 37 }
38 38
39 return 0; 39 return 0;
40 } 40 }
41 41
42 int spi_flash_cmd_write_status(struct spi_flash *flash, u8 ws) 42 int spi_flash_cmd_write_status(struct spi_flash *flash, u8 ws)
43 { 43 {
44 u8 cmd; 44 u8 cmd;
45 int ret; 45 int ret;
46 46
47 cmd = CMD_WRITE_STATUS; 47 cmd = CMD_WRITE_STATUS;
48 ret = spi_flash_write_common(flash, &cmd, 1, &ws, 1); 48 ret = spi_flash_write_common(flash, &cmd, 1, &ws, 1);
49 if (ret < 0) { 49 if (ret < 0) {
50 debug("SF: fail to write status register\n"); 50 debug("SF: fail to write status register\n");
51 return ret; 51 return ret;
52 } 52 }
53 53
54 return 0; 54 return 0;
55 } 55 }
56 56
57 #if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) 57 #if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND)
58 int spi_flash_cmd_read_config(struct spi_flash *flash, u8 *rc) 58 int spi_flash_cmd_read_config(struct spi_flash *flash, u8 *rc)
59 { 59 {
60 int ret; 60 int ret;
61 u8 cmd; 61 u8 cmd;
62 62
63 cmd = CMD_READ_CONFIG; 63 cmd = CMD_READ_CONFIG;
64 ret = spi_flash_read_common(flash, &cmd, 1, rc, 1); 64 ret = spi_flash_read_common(flash, &cmd, 1, rc, 1);
65 if (ret < 0) { 65 if (ret < 0) {
66 debug("SF: fail to read config register\n"); 66 debug("SF: fail to read config register\n");
67 return ret; 67 return ret;
68 } 68 }
69 69
70 return 0; 70 return 0;
71 } 71 }
72 72
73 int spi_flash_cmd_write_config(struct spi_flash *flash, u8 wc) 73 int spi_flash_cmd_write_config(struct spi_flash *flash, u8 wc)
74 { 74 {
75 u8 data[2]; 75 u8 data[2];
76 u8 cmd; 76 u8 cmd;
77 int ret; 77 int ret;
78 78
79 ret = spi_flash_cmd_read_status(flash, &data[0]); 79 ret = spi_flash_cmd_read_status(flash, &data[0]);
80 if (ret < 0) 80 if (ret < 0)
81 return ret; 81 return ret;
82 82
83 cmd = CMD_WRITE_STATUS; 83 cmd = CMD_WRITE_STATUS;
84 data[1] = wc; 84 data[1] = wc;
85 ret = spi_flash_write_common(flash, &cmd, 1, &data, 2); 85 ret = spi_flash_write_common(flash, &cmd, 1, &data, 2);
86 if (ret) { 86 if (ret) {
87 debug("SF: fail to write config register\n"); 87 debug("SF: fail to write config register\n");
88 return ret; 88 return ret;
89 } 89 }
90 90
91 return 0; 91 return 0;
92 } 92 }
93 #endif 93 #endif
94 94
95 #ifdef CONFIG_SPI_FLASH_BAR 95 #ifdef CONFIG_SPI_FLASH_BAR
96 static int spi_flash_cmd_bankaddr_write(struct spi_flash *flash, u8 bank_sel) 96 static int spi_flash_cmd_bankaddr_write(struct spi_flash *flash, u8 bank_sel)
97 { 97 {
98 u8 cmd; 98 u8 cmd;
99 int ret; 99 int ret;
100 100
101 if (flash->bank_curr == bank_sel) { 101 if (flash->bank_curr == bank_sel) {
102 debug("SF: not require to enable bank%d\n", bank_sel); 102 debug("SF: not require to enable bank%d\n", bank_sel);
103 return 0; 103 return 0;
104 } 104 }
105 105
106 cmd = flash->bank_write_cmd; 106 cmd = flash->bank_write_cmd;
107 ret = spi_flash_write_common(flash, &cmd, 1, &bank_sel, 1); 107 ret = spi_flash_write_common(flash, &cmd, 1, &bank_sel, 1);
108 if (ret < 0) { 108 if (ret < 0) {
109 debug("SF: fail to write bank register\n"); 109 debug("SF: fail to write bank register\n");
110 return ret; 110 return ret;
111 } 111 }
112 flash->bank_curr = bank_sel; 112 flash->bank_curr = bank_sel;
113 113
114 return 0; 114 return 0;
115 } 115 }
116 116
117 static int spi_flash_bank(struct spi_flash *flash, u32 offset) 117 static int spi_flash_bank(struct spi_flash *flash, u32 offset)
118 { 118 {
119 u8 bank_sel; 119 u8 bank_sel;
120 int ret; 120 int ret;
121 121
122 bank_sel = offset / SPI_FLASH_16MB_BOUN; 122 bank_sel = offset / SPI_FLASH_16MB_BOUN;
123 123
124 ret = spi_flash_cmd_bankaddr_write(flash, bank_sel); 124 ret = spi_flash_cmd_bankaddr_write(flash, bank_sel);
125 if (ret) { 125 if (ret) {
126 debug("SF: fail to set bank%d\n", bank_sel); 126 debug("SF: fail to set bank%d\n", bank_sel);
127 return ret; 127 return ret;
128 } 128 }
129 129
130 return 0; 130 return bank_sel;
131 } 131 }
132 #endif 132 #endif
133 133
134 int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout) 134 int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout)
135 { 135 {
136 struct spi_slave *spi = flash->spi; 136 struct spi_slave *spi = flash->spi;
137 unsigned long timebase; 137 unsigned long timebase;
138 int ret; 138 int ret;
139 u8 status; 139 u8 status;
140 u8 check_status = 0x0; 140 u8 check_status = 0x0;
141 u8 poll_bit = STATUS_WIP; 141 u8 poll_bit = STATUS_WIP;
142 u8 cmd = flash->poll_cmd; 142 u8 cmd = flash->poll_cmd;
143 143
144 if (cmd == CMD_FLAG_STATUS) { 144 if (cmd == CMD_FLAG_STATUS) {
145 poll_bit = STATUS_PEC; 145 poll_bit = STATUS_PEC;
146 check_status = poll_bit; 146 check_status = poll_bit;
147 } 147 }
148 148
149 ret = spi_xfer(spi, 8, &cmd, NULL, SPI_XFER_BEGIN); 149 ret = spi_xfer(spi, 8, &cmd, NULL, SPI_XFER_BEGIN);
150 if (ret) { 150 if (ret) {
151 debug("SF: fail to read %s status register\n", 151 debug("SF: fail to read %s status register\n",
152 cmd == CMD_READ_STATUS ? "read" : "flag"); 152 cmd == CMD_READ_STATUS ? "read" : "flag");
153 return ret; 153 return ret;
154 } 154 }
155 155
156 timebase = get_timer(0); 156 timebase = get_timer(0);
157 do { 157 do {
158 WATCHDOG_RESET(); 158 WATCHDOG_RESET();
159 159
160 ret = spi_xfer(spi, 8, NULL, &status, 0); 160 ret = spi_xfer(spi, 8, NULL, &status, 0);
161 if (ret) 161 if (ret)
162 return -1; 162 return -1;
163 163
164 if ((status & poll_bit) == check_status) 164 if ((status & poll_bit) == check_status)
165 break; 165 break;
166 166
167 } while (get_timer(timebase) < timeout); 167 } while (get_timer(timebase) < timeout);
168 168
169 spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END); 169 spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END);
170 170
171 if ((status & poll_bit) == check_status) 171 if ((status & poll_bit) == check_status)
172 return 0; 172 return 0;
173 173
174 /* Timed out */ 174 /* Timed out */
175 debug("SF: time out!\n"); 175 debug("SF: time out!\n");
176 return -1; 176 return -1;
177 } 177 }
178 178
179 int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd, 179 int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd,
180 size_t cmd_len, const void *buf, size_t buf_len) 180 size_t cmd_len, const void *buf, size_t buf_len)
181 { 181 {
182 struct spi_slave *spi = flash->spi; 182 struct spi_slave *spi = flash->spi;
183 unsigned long timeout = SPI_FLASH_PROG_TIMEOUT; 183 unsigned long timeout = SPI_FLASH_PROG_TIMEOUT;
184 int ret; 184 int ret;
185 185
186 if (buf == NULL) 186 if (buf == NULL)
187 timeout = SPI_FLASH_PAGE_ERASE_TIMEOUT; 187 timeout = SPI_FLASH_PAGE_ERASE_TIMEOUT;
188 188
189 ret = spi_claim_bus(flash->spi); 189 ret = spi_claim_bus(flash->spi);
190 if (ret) { 190 if (ret) {
191 debug("SF: unable to claim SPI bus\n"); 191 debug("SF: unable to claim SPI bus\n");
192 return ret; 192 return ret;
193 } 193 }
194 194
195 ret = spi_flash_cmd_write_enable(flash); 195 ret = spi_flash_cmd_write_enable(flash);
196 if (ret < 0) { 196 if (ret < 0) {
197 debug("SF: enabling write failed\n"); 197 debug("SF: enabling write failed\n");
198 return ret; 198 return ret;
199 } 199 }
200 200
201 ret = spi_flash_cmd_write(spi, cmd, cmd_len, buf, buf_len); 201 ret = spi_flash_cmd_write(spi, cmd, cmd_len, buf, buf_len);
202 if (ret < 0) { 202 if (ret < 0) {
203 debug("SF: write cmd failed\n"); 203 debug("SF: write cmd failed\n");
204 return ret; 204 return ret;
205 } 205 }
206 206
207 ret = spi_flash_cmd_wait_ready(flash, timeout); 207 ret = spi_flash_cmd_wait_ready(flash, timeout);
208 if (ret < 0) { 208 if (ret < 0) {
209 debug("SF: write %s timed out\n", 209 debug("SF: write %s timed out\n",
210 timeout == SPI_FLASH_PROG_TIMEOUT ? 210 timeout == SPI_FLASH_PROG_TIMEOUT ?
211 "program" : "page erase"); 211 "program" : "page erase");
212 return ret; 212 return ret;
213 } 213 }
214 214
215 spi_release_bus(spi); 215 spi_release_bus(spi);
216 216
217 return ret; 217 return ret;
218 } 218 }
219 219
220 int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len) 220 int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
221 { 221 {
222 u32 erase_size; 222 u32 erase_size;
223 u8 cmd[SPI_FLASH_CMD_LEN]; 223 u8 cmd[SPI_FLASH_CMD_LEN];
224 int ret = -1; 224 int ret = -1;
225 225
226 erase_size = flash->erase_size; 226 erase_size = flash->erase_size;
227 if (offset % erase_size || len % erase_size) { 227 if (offset % erase_size || len % erase_size) {
228 debug("SF: Erase offset/length not multiple of erase size\n"); 228 debug("SF: Erase offset/length not multiple of erase size\n");
229 return -1; 229 return -1;
230 } 230 }
231 231
232 cmd[0] = flash->erase_cmd; 232 cmd[0] = flash->erase_cmd;
233 while (len) { 233 while (len) {
234 #ifdef CONFIG_SPI_FLASH_BAR 234 #ifdef CONFIG_SPI_FLASH_BAR
235 ret = spi_flash_bank(flash, offset); 235 ret = spi_flash_bank(flash, offset);
236 if (ret < 0) 236 if (ret < 0)
237 return ret; 237 return ret;
238 #endif 238 #endif
239 spi_flash_addr(offset, cmd); 239 spi_flash_addr(offset, cmd);
240 240
241 debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], 241 debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
242 cmd[2], cmd[3], offset); 242 cmd[2], cmd[3], offset);
243 243
244 ret = spi_flash_write_common(flash, cmd, sizeof(cmd), NULL, 0); 244 ret = spi_flash_write_common(flash, cmd, sizeof(cmd), NULL, 0);
245 if (ret < 0) { 245 if (ret < 0) {
246 debug("SF: erase failed\n"); 246 debug("SF: erase failed\n");
247 break; 247 break;
248 } 248 }
249 249
250 offset += erase_size; 250 offset += erase_size;
251 len -= erase_size; 251 len -= erase_size;
252 } 252 }
253 253
254 return ret; 254 return ret;
255 } 255 }
256 256
257 int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset, 257 int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
258 size_t len, const void *buf) 258 size_t len, const void *buf)
259 { 259 {
260 unsigned long byte_addr, page_size; 260 unsigned long byte_addr, page_size;
261 size_t chunk_len, actual; 261 size_t chunk_len, actual;
262 u8 cmd[SPI_FLASH_CMD_LEN]; 262 u8 cmd[SPI_FLASH_CMD_LEN];
263 int ret = -1; 263 int ret = -1;
264 264
265 page_size = flash->page_size; 265 page_size = flash->page_size;
266 266
267 cmd[0] = flash->write_cmd; 267 cmd[0] = flash->write_cmd;
268 for (actual = 0; actual < len; actual += chunk_len) { 268 for (actual = 0; actual < len; actual += chunk_len) {
269 #ifdef CONFIG_SPI_FLASH_BAR 269 #ifdef CONFIG_SPI_FLASH_BAR
270 ret = spi_flash_bank(flash, offset); 270 ret = spi_flash_bank(flash, offset);
271 if (ret < 0) 271 if (ret < 0)
272 return ret; 272 return ret;
273 #endif 273 #endif
274 byte_addr = offset % page_size; 274 byte_addr = offset % page_size;
275 chunk_len = min(len - actual, page_size - byte_addr); 275 chunk_len = min(len - actual, page_size - byte_addr);
276 276
277 if (flash->spi->max_write_size) 277 if (flash->spi->max_write_size)
278 chunk_len = min(chunk_len, flash->spi->max_write_size); 278 chunk_len = min(chunk_len, flash->spi->max_write_size);
279 279
280 spi_flash_addr(offset, cmd); 280 spi_flash_addr(offset, cmd);
281 281
282 debug("SF: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n", 282 debug("SF: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
283 buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); 283 buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
284 284
285 ret = spi_flash_write_common(flash, cmd, sizeof(cmd), 285 ret = spi_flash_write_common(flash, cmd, sizeof(cmd),
286 buf + actual, chunk_len); 286 buf + actual, chunk_len);
287 if (ret < 0) { 287 if (ret < 0) {
288 debug("SF: write failed\n"); 288 debug("SF: write failed\n");
289 break; 289 break;
290 } 290 }
291 291
292 offset += chunk_len; 292 offset += chunk_len;
293 } 293 }
294 294
295 return ret; 295 return ret;
296 } 296 }
297 297
298 int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd, 298 int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd,
299 size_t cmd_len, void *data, size_t data_len) 299 size_t cmd_len, void *data, size_t data_len)
300 { 300 {
301 struct spi_slave *spi = flash->spi; 301 struct spi_slave *spi = flash->spi;
302 int ret; 302 int ret;
303 303
304 ret = spi_claim_bus(flash->spi); 304 ret = spi_claim_bus(flash->spi);
305 if (ret) { 305 if (ret) {
306 debug("SF: unable to claim SPI bus\n"); 306 debug("SF: unable to claim SPI bus\n");
307 return ret; 307 return ret;
308 } 308 }
309 309
310 ret = spi_flash_cmd_read(spi, cmd, cmd_len, data, data_len); 310 ret = spi_flash_cmd_read(spi, cmd, cmd_len, data, data_len);
311 if (ret < 0) { 311 if (ret < 0) {
312 debug("SF: read cmd failed\n"); 312 debug("SF: read cmd failed\n");
313 return ret; 313 return ret;
314 } 314 }
315 315
316 spi_release_bus(spi); 316 spi_release_bus(spi);
317 317
318 return ret; 318 return ret;
319 } 319 }
320 320
321 int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, 321 int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
322 size_t len, void *data) 322 size_t len, void *data)
323 { 323 {
324 u8 *cmd, cmdsz, bank_sel = 0; 324 u8 *cmd, cmdsz;
325 u32 remain_len, read_len; 325 u32 remain_len, read_len;
326 int bank_sel = 0;
326 int ret = -1; 327 int ret = -1;
327 328
328 /* Handle memory-mapped SPI */ 329 /* Handle memory-mapped SPI */
329 if (flash->memory_map) { 330 if (flash->memory_map) {
330 ret = spi_claim_bus(flash->spi); 331 ret = spi_claim_bus(flash->spi);
331 if (ret) { 332 if (ret) {
332 debug("SF: unable to claim SPI bus\n"); 333 debug("SF: unable to claim SPI bus\n");
333 return ret; 334 return ret;
334 } 335 }
335 spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MMAP); 336 spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MMAP);
336 memcpy(data, flash->memory_map + offset, len); 337 memcpy(data, flash->memory_map + offset, len);
337 spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MMAP_END); 338 spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MMAP_END);
338 spi_release_bus(flash->spi); 339 spi_release_bus(flash->spi);
339 return 0; 340 return 0;
340 } 341 }
341 342
342 cmdsz = SPI_FLASH_CMD_LEN + flash->dummy_byte; 343 cmdsz = SPI_FLASH_CMD_LEN + flash->dummy_byte;
343 cmd = malloc(cmdsz); 344 cmd = malloc(cmdsz);
344 memset(cmd, 0, cmdsz); 345 memset(cmd, 0, cmdsz);
345 346
346 cmd[0] = flash->read_cmd; 347 cmd[0] = flash->read_cmd;
347 while (len) { 348 while (len) {
348 #ifdef CONFIG_SPI_FLASH_BAR 349 #ifdef CONFIG_SPI_FLASH_BAR
349 bank_sel = offset / SPI_FLASH_16MB_BOUN; 350 bank_sel = spi_flash_bank(flash, offset);
350 351 if (bank_sel < 0)
351 ret = spi_flash_cmd_bankaddr_write(flash, bank_sel);
352 if (ret) {
353 debug("SF: fail to set bank%d\n", bank_sel);
354 return ret; 352 return ret;
355 }
356 #endif 353 #endif
357 remain_len = (SPI_FLASH_16MB_BOUN * (bank_sel + 1)) - offset; 354 remain_len = (SPI_FLASH_16MB_BOUN * (bank_sel + 1)) - offset;
358 if (len < remain_len) 355 if (len < remain_len)
359 read_len = len; 356 read_len = len;
360 else 357 else
361 read_len = remain_len; 358 read_len = remain_len;
362 359
363 spi_flash_addr(offset, cmd); 360 spi_flash_addr(offset, cmd);
364 361
365 ret = spi_flash_read_common(flash, cmd, cmdsz, data, read_len); 362 ret = spi_flash_read_common(flash, cmd, cmdsz, data, read_len);
366 if (ret < 0) { 363 if (ret < 0) {
367 debug("SF: read failed\n"); 364 debug("SF: read failed\n");
368 break; 365 break;
369 } 366 }
370 367
371 offset += read_len; 368 offset += read_len;
372 len -= read_len; 369 len -= read_len;
373 data += read_len; 370 data += read_len;
374 } 371 }
375 372
376 return ret; 373 return ret;
377 } 374 }
378 375
379 #ifdef CONFIG_SPI_FLASH_SST 376 #ifdef CONFIG_SPI_FLASH_SST
380 static int sst_byte_write(struct spi_flash *flash, u32 offset, const void *buf) 377 static int sst_byte_write(struct spi_flash *flash, u32 offset, const void *buf)
381 { 378 {
382 int ret; 379 int ret;
383 u8 cmd[4] = { 380 u8 cmd[4] = {
384 CMD_SST_BP, 381 CMD_SST_BP,
385 offset >> 16, 382 offset >> 16,
386 offset >> 8, 383 offset >> 8,
387 offset, 384 offset,
388 }; 385 };
389 386
390 debug("BP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n", 387 debug("BP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n",
391 spi_w8r8(flash->spi, CMD_READ_STATUS), buf, cmd[0], offset); 388 spi_w8r8(flash->spi, CMD_READ_STATUS), buf, cmd[0], offset);
392 389
393 ret = spi_flash_cmd_write_enable(flash); 390 ret = spi_flash_cmd_write_enable(flash);
394 if (ret) 391 if (ret)
395 return ret; 392 return ret;
396 393
397 ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), buf, 1); 394 ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), buf, 1);
398 if (ret) 395 if (ret)
399 return ret; 396 return ret;
400 397
401 return spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT); 398 return spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
402 } 399 }
403 400
404 int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len, 401 int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len,
405 const void *buf) 402 const void *buf)
406 { 403 {
407 size_t actual, cmd_len; 404 size_t actual, cmd_len;
408 int ret; 405 int ret;
409 u8 cmd[4]; 406 u8 cmd[4];
410 407
411 ret = spi_claim_bus(flash->spi); 408 ret = spi_claim_bus(flash->spi);
412 if (ret) { 409 if (ret) {
413 debug("SF: Unable to claim SPI bus\n"); 410 debug("SF: Unable to claim SPI bus\n");
414 return ret; 411 return ret;
415 } 412 }
416 413
417 /* If the data is not word aligned, write out leading single byte */ 414 /* If the data is not word aligned, write out leading single byte */
418 actual = offset % 2; 415 actual = offset % 2;
419 if (actual) { 416 if (actual) {
420 ret = sst_byte_write(flash, offset, buf); 417 ret = sst_byte_write(flash, offset, buf);
421 if (ret) 418 if (ret)
422 goto done; 419 goto done;
423 } 420 }
424 offset += actual; 421 offset += actual;
425 422
426 ret = spi_flash_cmd_write_enable(flash); 423 ret = spi_flash_cmd_write_enable(flash);
427 if (ret) 424 if (ret)
428 goto done; 425 goto done;
429 426
430 cmd_len = 4; 427 cmd_len = 4;
431 cmd[0] = CMD_SST_AAI_WP; 428 cmd[0] = CMD_SST_AAI_WP;
432 cmd[1] = offset >> 16; 429 cmd[1] = offset >> 16;
433 cmd[2] = offset >> 8; 430 cmd[2] = offset >> 8;
434 cmd[3] = offset; 431 cmd[3] = offset;
435 432
436 for (; actual < len - 1; actual += 2) { 433 for (; actual < len - 1; actual += 2) {
437 debug("WP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n", 434 debug("WP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n",
438 spi_w8r8(flash->spi, CMD_READ_STATUS), buf + actual, 435 spi_w8r8(flash->spi, CMD_READ_STATUS), buf + actual,
439 cmd[0], offset); 436 cmd[0], offset);
440 437
441 ret = spi_flash_cmd_write(flash->spi, cmd, cmd_len, 438 ret = spi_flash_cmd_write(flash->spi, cmd, cmd_len,
442 buf + actual, 2); 439 buf + actual, 2);
443 if (ret) { 440 if (ret) {
444 debug("SF: sst word program failed\n"); 441 debug("SF: sst word program failed\n");
445 break; 442 break;
446 } 443 }
447 444
448 ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT); 445 ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
449 if (ret) 446 if (ret)
450 break; 447 break;
451 448
452 cmd_len = 1; 449 cmd_len = 1;
453 offset += 2; 450 offset += 2;
454 } 451 }
455 452
456 if (!ret) 453 if (!ret)
457 ret = spi_flash_cmd_write_disable(flash); 454 ret = spi_flash_cmd_write_disable(flash);
458 455
459 /* If there is a single trailing byte, write it out */ 456 /* If there is a single trailing byte, write it out */
460 if (!ret && actual != len) 457 if (!ret && actual != len)
461 ret = sst_byte_write(flash, offset, buf + actual); 458 ret = sst_byte_write(flash, offset, buf + actual);
462 459
463 done: 460 done:
464 debug("SF: sst: program %s %zu bytes @ 0x%zx\n", 461 debug("SF: sst: program %s %zu bytes @ 0x%zx\n",
465 ret ? "failure" : "success", len, offset - actual); 462 ret ? "failure" : "success", len, offset - actual);
466 463
467 spi_release_bus(flash->spi); 464 spi_release_bus(flash->spi);
468 return ret; 465 return ret;
469 } 466 }
470 #endif 467 #endif