flash/nor: Use proper data types in driver API
[fw/openocd] / src / flash / nor / esirisc_flash.c
1 /***************************************************************************
2  *   Copyright (C) 2018 by Square, Inc.                                    *
3  *   Steven Stallion <stallion@squareup.com>                               *
4  *   James Zhao <hjz@squareup.com>                                         *
5  *                                                                         *
6  *   This program is free software; you can redistribute it and/or modify  *
7  *   it under the terms of the GNU General Public License as published by  *
8  *   the Free Software Foundation; either version 2 of the License, or     *
9  *   (at your option) any later version.                                   *
10  *                                                                         *
11  *   This program is distributed in the hope that it will be useful,       *
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14  *   GNU General Public License for more details.                          *
15  *                                                                         *
16  *   You should have received a copy of the GNU General Public License     *
17  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
18  ***************************************************************************/
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <flash/common.h>
25 #include <flash/nor/imp.h>
26 #include <helper/command.h>
27 #include <helper/log.h>
28 #include <helper/time_support.h>
29 #include <helper/types.h>
30 #include <target/esirisc.h>
31 #include <target/target.h>
32
33 /* eSi-TSMC Flash Registers */
34 #define CONTROL                         0x00    /* Control Register */
35 #define TIMING0                         0x04    /* Timing Register 0 */
36 #define TIMING1                         0x08    /* Timing Register 1 */
37 #define TIMING2                         0x0c    /* Timing Register 2 */
38 #define UNLOCK1                         0x18    /* Unlock 1 */
39 #define UNLOCK2                         0x1c    /* Unlock 2 */
40 #define ADDRESS                         0x20    /* Erase/Program Address */
41 #define PB_DATA                         0x24    /* Program Buffer Data */
42 #define PB_INDEX                        0x28    /* Program Buffer Index */
43 #define STATUS                          0x2c    /* Status Register */
44 #define REDUN_0                         0x30    /* Redundant Address 0 */
45 #define REDUN_1                         0x34    /* Redundant Address 1 */
46
47 /* Control Fields */
48 #define CONTROL_SLM                     (1<<0)  /* Sleep Mode */
49 #define CONTROL_WP                      (1<<1)  /* Register Write Protect */
50 #define CONTROL_E                       (1<<3)  /* Erase */
51 #define CONTROL_EP                      (1<<4)  /* Erase Page */
52 #define CONTROL_P                       (1<<5)  /* Program Flash */
53 #define CONTROL_ERC                     (1<<6)  /* Erase Reference Cell */
54 #define CONTROL_R                       (1<<7)  /* Recall Trim Code */
55 #define CONTROL_AP                      (1<<8)  /* Auto-Program */
56
57 /* Timing Fields */
58 #define TIMING0_R(x)            (((x) <<  0) & 0x3f)            /* Read Wait States */
59 #define TIMING0_F(x)            (((x) << 16) & 0xffff0000)      /* Tnvh Clock Cycles */
60 #define TIMING1_E(x)            (((x) <<  0) & 0xffffff)        /* Tme/Terase/Tre Clock Cycles */
61 #define TIMING2_P(x)            (((x) <<  0) & 0xffff)          /* Tprog Clock Cycles */
62 #define TIMING2_H(x)            (((x) << 16) & 0xff0000)        /* Clock Cycles in 100ns */
63 #define TIMING2_T(x)            (((x) << 24) & 0xf000000)       /* Clock Cycles in 10ns */
64
65 /* Status Fields */
66 #define STATUS_BUSY                     (1<<0)  /* Busy (Erase/Program) */
67 #define STATUS_WER                      (1<<1)  /* Write Protect Error */
68 #define STATUS_DR                       (1<<2)  /* Disable Redundancy */
69 #define STATUS_DIS                      (1<<3)  /* Discharged */
70 #define STATUS_BO                       (1<<4)  /* Brown Out */
71
72 /* Redundant Address Fields */
73 #define REDUN_R                         (1<<0)                                          /* Used */
74 #define REDUN_P(x)                      (((x) << 12) & 0x7f000)         /* Redundant Page Address */
75
76 /*
77  * The eSi-TSMC Flash manual provides two sets of timings based on the
78  * underlying flash process. By default, 90nm is assumed.
79  */
80 #if 0 /* 55nm */
81 #define TNVH                            5000            /* 5us   */
82 #define TME                                     80000000        /* 80ms  */
83 #define TERASE                          160000000       /* 160ms */
84 #define TRE                                     100000000       /* 100ms */
85 #define TPROG                           8000            /* 8us   */
86 #else /* 90nm */
87 #define TNVH                            5000            /* 5us   */
88 #define TME                                     20000000        /* 20ms  */
89 #define TERASE                          40000000        /* 40ms  */
90 #define TRE                                     40000000        /* 40ms  */
91 #define TPROG                           40000           /* 40us  */
92 #endif
93
94 #define CONTROL_TIMEOUT         5000            /* 5s    */
95 #define FLASH_PAGE_SIZE         4096
96 #define PB_MAX                          32
97
98 #define NUM_NS_PER_S            1000000000ULL
99
100 struct esirisc_flash_bank {
101         bool probed;
102         uint32_t cfg;
103         uint32_t clock;
104         uint32_t wait_states;
105 };
106
107 static const struct command_registration esirisc_flash_command_handlers[];
108
109 FLASH_BANK_COMMAND_HANDLER(esirisc_flash_bank_command)
110 {
111         struct esirisc_flash_bank *esirisc_info;
112         struct command *esirisc_cmd;
113
114         if (CMD_ARGC < 9)
115                 return ERROR_COMMAND_SYNTAX_ERROR;
116
117         esirisc_info = calloc(1, sizeof(struct esirisc_flash_bank));
118
119         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], esirisc_info->cfg);
120         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[7], esirisc_info->clock);
121         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[8], esirisc_info->wait_states);
122
123         bank->driver_priv = esirisc_info;
124
125         /* register commands using existing esirisc context */
126         esirisc_cmd = command_find_in_context(CMD_CTX, "esirisc");
127         register_commands(CMD_CTX, esirisc_cmd, esirisc_flash_command_handlers);
128
129         return ERROR_OK;
130 }
131
132 /*
133  * Register writes are ignored if the control.WP flag is set; the
134  * following sequence is required to modify this flag even when
135  * protection is disabled.
136  */
137 static int esirisc_flash_unlock(struct flash_bank *bank)
138 {
139         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
140         struct target *target = bank->target;
141
142         target_write_u32(target, esirisc_info->cfg + UNLOCK1, 0x7123);
143         target_write_u32(target, esirisc_info->cfg + UNLOCK2, 0x812a);
144         target_write_u32(target, esirisc_info->cfg + UNLOCK1, 0xbee1);
145
146         return ERROR_OK;
147 }
148
149 static int esirisc_flash_disable_protect(struct flash_bank *bank)
150 {
151         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
152         struct target *target = bank->target;
153         uint32_t control;
154
155         target_read_u32(target, esirisc_info->cfg + CONTROL, &control);
156         if (!(control & CONTROL_WP))
157                 return ERROR_OK;
158
159         (void)esirisc_flash_unlock(bank);
160
161         control &= ~CONTROL_WP;
162
163         target_write_u32(target, esirisc_info->cfg + CONTROL, control);
164
165         return ERROR_OK;
166 }
167
168 static int esirisc_flash_enable_protect(struct flash_bank *bank)
169 {
170         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
171         struct target *target = bank->target;
172         uint32_t control;
173
174         target_read_u32(target, esirisc_info->cfg + CONTROL, &control);
175         if (control & CONTROL_WP)
176                 return ERROR_OK;
177
178         (void)esirisc_flash_unlock(bank);
179
180         control |= CONTROL_WP;
181
182         target_write_u32(target, esirisc_info->cfg + CONTROL, control);
183
184         return ERROR_OK;
185 }
186
187 static int esirisc_flash_check_status(struct flash_bank *bank)
188 {
189         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
190         struct target *target = bank->target;
191         uint32_t status;
192
193         target_read_u32(target, esirisc_info->cfg + STATUS, &status);
194         if (status & STATUS_WER) {
195                 LOG_ERROR("%s: bad status: 0x%" PRIx32, bank->name, status);
196                 return ERROR_FLASH_OPERATION_FAILED;
197         }
198
199         return ERROR_OK;
200 }
201
202 static int esirisc_flash_clear_status(struct flash_bank *bank)
203 {
204         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
205         struct target *target = bank->target;
206
207         target_write_u32(target, esirisc_info->cfg + STATUS, STATUS_WER);
208
209         return ERROR_OK;
210 }
211
212 static int esirisc_flash_wait(struct flash_bank *bank, int ms)
213 {
214         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
215         struct target *target = bank->target;
216         uint32_t status;
217         int64_t t;
218
219         t = timeval_ms();
220         for (;;) {
221                 target_read_u32(target, esirisc_info->cfg + STATUS, &status);
222                 if (!(status & STATUS_BUSY))
223                         return ERROR_OK;
224
225                 if ((timeval_ms() - t) > ms)
226                         return ERROR_TARGET_TIMEOUT;
227
228                 keep_alive();
229         }
230 }
231
232 static int esirisc_flash_control(struct flash_bank *bank, uint32_t control)
233 {
234         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
235         struct target *target = bank->target;
236
237         esirisc_flash_clear_status(bank);
238
239         target_write_u32(target, esirisc_info->cfg + CONTROL, control);
240
241         int retval = esirisc_flash_wait(bank, CONTROL_TIMEOUT);
242         if (retval != ERROR_OK) {
243                 LOG_ERROR("%s: control timed out: 0x%" PRIx32, bank->name, control);
244                 return retval;
245         }
246
247         return esirisc_flash_check_status(bank);
248 }
249
250 static int esirisc_flash_recall(struct flash_bank *bank)
251 {
252         return esirisc_flash_control(bank, CONTROL_R);
253 }
254
255 static int esirisc_flash_erase(struct flash_bank *bank, unsigned int first,
256                 unsigned int last)
257 {
258         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
259         struct target *target = bank->target;
260         int retval = ERROR_OK;
261
262         if (target->state != TARGET_HALTED)
263                 return ERROR_TARGET_NOT_HALTED;
264
265         (void)esirisc_flash_disable_protect(bank);
266
267         for (unsigned int page = first; page < last; ++page) {
268                 uint32_t address = page * FLASH_PAGE_SIZE;
269
270                 target_write_u32(target, esirisc_info->cfg + ADDRESS, address);
271
272                 retval = esirisc_flash_control(bank, CONTROL_EP);
273                 if (retval != ERROR_OK) {
274                         LOG_ERROR("%s: failed to erase address: 0x%" PRIx32, bank->name, address);
275                         break;
276                 }
277         }
278
279         (void)esirisc_flash_enable_protect(bank);
280
281         return retval;
282 }
283
284 static int esirisc_flash_mass_erase(struct flash_bank *bank)
285 {
286         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
287         struct target *target = bank->target;
288         int retval;
289
290         if (target->state != TARGET_HALTED)
291                 return ERROR_TARGET_NOT_HALTED;
292
293         (void)esirisc_flash_disable_protect(bank);
294
295         target_write_u32(target, esirisc_info->cfg + ADDRESS, 0);
296
297         retval = esirisc_flash_control(bank, CONTROL_E);
298         if (retval != ERROR_OK)
299                 LOG_ERROR("%s: failed to mass erase", bank->name);
300
301         (void)esirisc_flash_enable_protect(bank);
302
303         return retval;
304 }
305
306 /*
307  * Per TSMC, the reference cell should be erased once per sample. This
308  * is typically done during wafer sort, however we include support for
309  * those that may need to calibrate flash at a later time.
310  */
311 static int esirisc_flash_ref_erase(struct flash_bank *bank)
312 {
313         struct target *target = bank->target;
314         int retval;
315
316         if (target->state != TARGET_HALTED)
317                 return ERROR_TARGET_NOT_HALTED;
318
319         (void)esirisc_flash_disable_protect(bank);
320
321         retval = esirisc_flash_control(bank, CONTROL_ERC);
322         if (retval != ERROR_OK)
323                 LOG_ERROR("%s: failed to erase reference cell", bank->name);
324
325         (void)esirisc_flash_enable_protect(bank);
326
327         return retval;
328 }
329
330 static int esirisc_flash_fill_pb(struct flash_bank *bank,
331                 const uint8_t *buffer, uint32_t count)
332 {
333         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
334         struct target *target = bank->target;
335         struct esirisc_common *esirisc = target_to_esirisc(target);
336
337         /*
338          * The pb_index register is auto-incremented when pb_data is written
339          * and should be cleared before each operation.
340          */
341         target_write_u32(target, esirisc_info->cfg + PB_INDEX, 0);
342
343         /*
344          * The width of the pb_data register depends on the underlying
345          * target; writing one byte at a time incurs a significant
346          * performance penalty and should be avoided.
347          */
348         while (count > 0) {
349                 uint32_t max_bytes = DIV_ROUND_UP(esirisc->num_bits, 8);
350                 uint32_t num_bytes = MIN(count, max_bytes);
351
352                 target_write_buffer(target, esirisc_info->cfg + PB_DATA, num_bytes, buffer);
353
354                 buffer += num_bytes;
355                 count -= num_bytes;
356         }
357
358         return ERROR_OK;
359 }
360
361 static int esirisc_flash_write(struct flash_bank *bank,
362                 const uint8_t *buffer, uint32_t offset, uint32_t count)
363 {
364         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
365         struct target *target = bank->target;
366         int retval = ERROR_OK;
367
368         if (target->state != TARGET_HALTED)
369                 return ERROR_TARGET_NOT_HALTED;
370
371         (void)esirisc_flash_disable_protect(bank);
372
373         /*
374          * The address register is auto-incremented based on the contents of
375          * the pb_index register after each operation completes. It can be
376          * set once provided pb_index is cleared before each operation.
377          */
378         target_write_u32(target, esirisc_info->cfg + ADDRESS, offset);
379
380         /*
381          * Care must be taken when filling the program buffer; a maximum of
382          * 32 bytes may be written at a time and may not cross a 32-byte
383          * boundary based on the current offset.
384          */
385         while (count > 0) {
386                 uint32_t max_bytes = PB_MAX - (offset & 0x1f);
387                 uint32_t num_bytes = MIN(count, max_bytes);
388
389                 esirisc_flash_fill_pb(bank, buffer, num_bytes);
390
391                 retval = esirisc_flash_control(bank, CONTROL_P);
392                 if (retval != ERROR_OK) {
393                         LOG_ERROR("%s: failed to program address: 0x%" PRIx32, bank->name, offset);
394                         break;
395                 }
396
397                 buffer += num_bytes;
398                 offset += num_bytes;
399                 count -= num_bytes;
400         }
401
402         (void)esirisc_flash_enable_protect(bank);
403
404         return retval;
405 }
406
407 static uint32_t esirisc_flash_num_cycles(struct flash_bank *bank, uint64_t ns)
408 {
409         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
410
411         /* apply scaling factor to avoid truncation */
412         uint64_t hz = (uint64_t)esirisc_info->clock * 1000;
413         uint64_t num_cycles = ((hz / NUM_NS_PER_S) * ns) / 1000;
414
415         if (hz % NUM_NS_PER_S > 0)
416                 num_cycles++;
417
418         return num_cycles;
419 }
420
421 static int esirisc_flash_init(struct flash_bank *bank)
422 {
423         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
424         struct target *target = bank->target;
425         uint32_t value;
426         int retval;
427
428         (void)esirisc_flash_disable_protect(bank);
429
430         /* initialize timing registers */
431         value = TIMING0_F(esirisc_flash_num_cycles(bank, TNVH))
432                         | TIMING0_R(esirisc_info->wait_states);
433
434         LOG_DEBUG("TIMING0: 0x%" PRIx32, value);
435         target_write_u32(target, esirisc_info->cfg + TIMING0, value);
436
437         value = TIMING1_E(esirisc_flash_num_cycles(bank, TERASE));
438
439         LOG_DEBUG("TIMING1: 0x%" PRIx32, value);
440         target_write_u32(target, esirisc_info->cfg + TIMING1, value);
441
442         value = TIMING2_T(esirisc_flash_num_cycles(bank, 10))
443                         | TIMING2_H(esirisc_flash_num_cycles(bank, 100))
444                         | TIMING2_P(esirisc_flash_num_cycles(bank, TPROG));
445
446         LOG_DEBUG("TIMING2: 0x%" PRIx32, value);
447         target_write_u32(target, esirisc_info->cfg + TIMING2, value);
448
449         /* recall trim code */
450         retval = esirisc_flash_recall(bank);
451         if (retval != ERROR_OK)
452                 LOG_ERROR("%s: failed to recall trim code", bank->name);
453
454         (void)esirisc_flash_enable_protect(bank);
455
456         return retval;
457 }
458
459 static int esirisc_flash_probe(struct flash_bank *bank)
460 {
461         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
462         struct target *target = bank->target;
463         int retval;
464
465         if (target->state != TARGET_HALTED)
466                 return ERROR_TARGET_NOT_HALTED;
467
468         bank->num_sectors = bank->size / FLASH_PAGE_SIZE;
469         bank->sectors = alloc_block_array(0, FLASH_PAGE_SIZE, bank->num_sectors);
470
471         retval = esirisc_flash_init(bank);
472         if (retval != ERROR_OK) {
473                 LOG_ERROR("%s: failed to initialize bank", bank->name);
474                 return retval;
475         }
476
477         esirisc_info->probed = true;
478
479         return ERROR_OK;
480 }
481
482 static int esirisc_flash_auto_probe(struct flash_bank *bank)
483 {
484         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
485
486         if (esirisc_info->probed)
487                 return ERROR_OK;
488
489         return esirisc_flash_probe(bank);
490 }
491
492 static int esirisc_flash_info(struct flash_bank *bank, char *buf, int buf_size)
493 {
494         struct esirisc_flash_bank *esirisc_info = bank->driver_priv;
495
496         snprintf(buf, buf_size,
497                         "%4s cfg at 0x%" PRIx32 ", clock %" PRId32 ", wait_states %" PRId32,
498                         "",     /* align with first line */
499                         esirisc_info->cfg,
500                         esirisc_info->clock,
501                         esirisc_info->wait_states);
502
503         return ERROR_OK;
504 }
505
506 COMMAND_HANDLER(handle_esirisc_flash_mass_erase_command)
507 {
508         struct flash_bank *bank;
509         int retval;
510
511         if (CMD_ARGC < 1)
512                 return ERROR_COMMAND_SYNTAX_ERROR;
513
514         retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
515         if (retval != ERROR_OK)
516                 return retval;
517
518         retval = esirisc_flash_mass_erase(bank);
519
520         command_print(CMD, "mass erase %s",
521                         (retval == ERROR_OK) ? "successful" : "failed");
522
523         return retval;
524 }
525
526 COMMAND_HANDLER(handle_esirisc_flash_ref_erase_command)
527 {
528         struct flash_bank *bank;
529         int retval;
530
531         if (CMD_ARGC < 1)
532                 return ERROR_COMMAND_SYNTAX_ERROR;
533
534         retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
535         if (retval != ERROR_OK)
536                 return retval;
537
538         retval = esirisc_flash_ref_erase(bank);
539
540         command_print(CMD, "erase reference cell %s",
541                         (retval == ERROR_OK) ? "successful" : "failed");
542
543         return retval;
544 }
545
546 static const struct command_registration esirisc_flash_exec_command_handlers[] = {
547         {
548                 .name = "mass_erase",
549                 .handler = handle_esirisc_flash_mass_erase_command,
550                 .mode = COMMAND_EXEC,
551                 .help = "erase all pages in data memory",
552                 .usage = "bank_id",
553         },
554         {
555                 .name = "ref_erase",
556                 .handler = handle_esirisc_flash_ref_erase_command,
557                 .mode = COMMAND_EXEC,
558                 .help = "erase reference cell (uncommon)",
559                 .usage = "bank_id",
560         },
561         COMMAND_REGISTRATION_DONE
562 };
563
564 static const struct command_registration esirisc_flash_command_handlers[] = {
565         {
566                 .name = "flash",
567                 .mode = COMMAND_EXEC,
568                 .help = "eSi-TSMC Flash command group",
569                 .usage = "",
570                 .chain = esirisc_flash_exec_command_handlers,
571         },
572         COMMAND_REGISTRATION_DONE
573 };
574
575 const struct flash_driver esirisc_flash = {
576         .name = "esirisc",
577         .usage = "flash bank bank_id 'esirisc' base_address size_bytes 0 0 target "
578                         "cfg_address clock_hz wait_states",
579         .flash_bank_command = esirisc_flash_bank_command,
580         .erase = esirisc_flash_erase,
581         .write = esirisc_flash_write,
582         .read = default_flash_read,
583         .probe = esirisc_flash_probe,
584         .auto_probe = esirisc_flash_auto_probe,
585         .erase_check = default_flash_blank_check,
586         .info = esirisc_flash_info,
587         .free_driver_priv = default_flash_free_driver_priv,
588 };