bluenrg-x: added support for BlueNRG-LP device
[fw/openocd] / src / flash / nor / bluenrg-x.c
1 /***************************************************************************
2  *   Copyright (C) 2017 by Michele Sardo                                   *
3  *   msmttchr@gmail.com                                                    *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
17  ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include <target/algorithm.h>
24 #include <target/armv7m.h>
25 #include <target/cortex_m.h>
26 #include "imp.h"
27
28 #define BLUENRG2_IDCODE      (0x0200A041)
29 #define BLUENRGLP_IDCODE     (0x0201E041)
30 #define BLUENRG2_JTAG_REG        (flash_priv_data_2.jtag_idcode_reg)
31 #define BLUENRGLP_JTAG_REG       (flash_priv_data_lp.jtag_idcode_reg)
32
33 #define FLASH_SIZE_REG(bluenrgx_info)       (bluenrgx_info->flash_ptr->flash_size_reg)
34 #define DIE_ID_REG(bluenrgx_info)           (bluenrgx_info->flash_ptr->die_id_reg)
35 #define JTAG_IDCODE_REG(bluenrgx_info)      (bluenrgx_info->flash_ptr->jtag_idcode_reg)
36 #define FLASH_BASE(bluenrgx_info)           (bluenrgx_info->flash_ptr->flash_base)
37 #define FLASH_PAGE_SIZE(bluenrgx_info)      (bluenrgx_info->flash_ptr->flash_page_size)
38 #define FLASH_REG_COMMAND(bluenrgx_info)    (bluenrgx_info->flash_ptr->flash_reg_command)
39 #define FLASH_REG_IRQRAW(bluenrgx_info)     (bluenrgx_info->flash_ptr->flash_reg_irqraw)
40 #define FLASH_REG_ADDRESS(bluenrgx_info)    (bluenrgx_info->flash_ptr->flash_reg_address)
41 #define FLASH_REG_DATA(bluenrgx_info)       (bluenrgx_info->flash_ptr->flash_reg_data)
42 #define FLASH_CMD_ERASE_PAGE 0x11
43 #define FLASH_CMD_MASSERASE  0x22
44 #define FLASH_CMD_WRITE      0x33
45 #define FLASH_CMD_BURSTWRITE 0xCC
46 #define FLASH_INT_CMDDONE    0x01
47 #define FLASH_WORD_LEN       4
48
49 /* See contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c for source and
50  * hints how to generate the data!
51  */
52 static const uint8_t bluenrgx_flash_write_code_2[] = {
53 #include "../../../contrib/loaders/flash/bluenrg-x/bluenrg-2_write.inc"
54                         };
55
56 static const uint8_t bluenrgx_flash_write_code_lp[] = {
57 #include "../../../contrib/loaders/flash/bluenrg-x/bluenrg-lp_write.inc"
58                         };
59
60 struct flash_ctrl_priv_data {
61         uint32_t flash_size_reg;
62         uint32_t die_id_reg;
63         uint32_t jtag_idcode_reg;
64         uint32_t flash_base;
65         uint32_t flash_page_size;
66         uint32_t flash_reg_command;
67         uint32_t flash_reg_irqraw;
68         uint32_t flash_reg_address;
69         uint32_t flash_reg_data;
70         uint32_t jtag_idcode;
71         char *part_name;
72         const uint8_t *flash_write_code;
73         uint32_t flash_write_code_size;
74 };
75
76 const struct flash_ctrl_priv_data flash_priv_data_1 = {
77         .flash_size_reg = 0x40100014,
78         .die_id_reg = 0x4090001C,
79         .jtag_idcode_reg = 0x40900028,
80         .flash_base = 0x10040000,
81         .flash_page_size = 2048,
82         .flash_reg_command = 0x40100000,
83         .flash_reg_irqraw = 0x40100010,
84         .flash_reg_address = 0x40100018,
85         .flash_reg_data = 0x40100040,
86         .jtag_idcode = 0x00000000,
87         .part_name = "BLUENRG-1",
88         .flash_write_code = bluenrgx_flash_write_code_2,
89         .flash_write_code_size = sizeof(bluenrgx_flash_write_code_2),
90 };
91
92 const struct flash_ctrl_priv_data flash_priv_data_2 = {
93         .flash_size_reg = 0x40100014,
94         .die_id_reg = 0x4090001C,
95         .jtag_idcode_reg = 0x40900028,
96         .flash_base = 0x10040000,
97         .flash_page_size = 2048,
98         .flash_reg_command = 0x40100000,
99         .flash_reg_irqraw = 0x40100010,
100         .flash_reg_address = 0x40100018,
101         .flash_reg_data = 0x40100040,
102         .jtag_idcode = BLUENRG2_IDCODE,
103         .part_name = "BLUENRG-2",
104         .flash_write_code = bluenrgx_flash_write_code_2,
105         .flash_write_code_size = sizeof(bluenrgx_flash_write_code_2),
106 };
107
108 const struct flash_ctrl_priv_data flash_priv_data_lp = {
109         .flash_size_reg = 0x40001014,
110         .die_id_reg = 0x40000000,
111         .jtag_idcode_reg = 0x40000004,
112         .flash_base = 0x10040000,
113         .flash_page_size = 2048,
114         .flash_reg_command = 0x40001000,
115         .flash_reg_irqraw = 0x40001010,
116         .flash_reg_address = 0x40001018,
117         .flash_reg_data = 0x40001040,
118         .jtag_idcode = BLUENRGLP_IDCODE,
119         .part_name = "BLUENRG-LP",
120         .flash_write_code = bluenrgx_flash_write_code_lp,
121         .flash_write_code_size = sizeof(bluenrgx_flash_write_code_lp),
122 };
123
124 struct bluenrgx_flash_bank {
125         int probed;
126         uint32_t die_id;
127         const struct flash_ctrl_priv_data *flash_ptr;
128         const uint8_t *flash_write_code;
129         uint32_t flash_write_code_size;
130 };
131
132 const struct flash_ctrl_priv_data *flash_ctrl[] = {&flash_priv_data_1, &flash_priv_data_2, &flash_priv_data_lp};
133
134 static int bluenrgx_protect_check(struct flash_bank *bank)
135 {
136         /* Nothing to do. Protection is only handled in SW. */
137         return ERROR_OK;
138 }
139
140 /* flash_bank bluenrg-x 0 0 0 0 <target#> */
141 FLASH_BANK_COMMAND_HANDLER(bluenrgx_flash_bank_command)
142 {
143         struct bluenrgx_flash_bank *bluenrgx_info;
144         /* Create the bank structure */
145         bluenrgx_info = calloc(1, sizeof(*bluenrgx_info));
146
147         /* Check allocation */
148         if (bluenrgx_info == NULL) {
149                 LOG_ERROR("failed to allocate bank structure");
150                 return ERROR_FAIL;
151         }
152
153         bank->driver_priv = bluenrgx_info;
154
155         bluenrgx_info->probed = 0;
156
157         if (CMD_ARGC < 6)
158                 return ERROR_COMMAND_SYNTAX_ERROR;
159
160         return ERROR_OK;
161 }
162
163 static int bluenrgx_erase(struct flash_bank *bank, int first, int last)
164 {
165         int retval = ERROR_OK;
166         struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;
167         int num_sectors = (last - first + 1);
168         int mass_erase = (num_sectors == bank->num_sectors);
169         struct target *target = bank->target;
170         uint32_t address, command;
171
172         /* check preconditions */
173         if (bluenrgx_info->probed == 0)
174                 return ERROR_FLASH_BANK_NOT_PROBED;
175
176         if (bank->target->state != TARGET_HALTED) {
177                 LOG_ERROR("Target not halted");
178                 return ERROR_TARGET_NOT_HALTED;
179         }
180         /* Disable blue module */
181         if (target_write_u32(target, 0x200000c0, 0) != ERROR_OK) {
182                 LOG_ERROR("Blue disable failed");
183                 return ERROR_FAIL;
184         }
185
186         if (mass_erase) {
187                 command = FLASH_CMD_MASSERASE;
188                 address = bank->base;
189                 if (target_write_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), 0x3f) != ERROR_OK) {
190                         LOG_ERROR("Register write failed");
191                         return ERROR_FAIL;
192                 }
193
194                 if (target_write_u32(target, FLASH_REG_ADDRESS(bluenrgx_info),
195                                                                 (address - FLASH_BASE(bluenrgx_info)) >> 2) != ERROR_OK) {
196                         LOG_ERROR("Register write failed");
197                         return ERROR_FAIL;
198                 }
199
200                 if (target_write_u32(target, FLASH_REG_COMMAND(bluenrgx_info), command) != ERROR_OK) {
201                         LOG_ERROR("Register write failed");
202                         return ERROR_FAIL;
203                 }
204
205                 for (int i = 0; i < 100; i++) {
206                         uint32_t value;
207                         if (target_read_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), &value)) {
208                                 LOG_ERROR("Register write failed");
209                                 return ERROR_FAIL;
210                         }
211                         if (value & FLASH_INT_CMDDONE)
212                                 break;
213                         if (i == 99) {
214                                 LOG_ERROR("Mass erase command failed (timeout)");
215                                 retval = ERROR_FAIL;
216                         }
217                 }
218
219         } else {
220                 command = FLASH_CMD_ERASE_PAGE;
221                 for (int i = first; i <= last; i++) {
222                         address = bank->base+i*FLASH_PAGE_SIZE(bluenrgx_info);
223                         LOG_DEBUG("address = %08x, index = %d", address, i);
224
225                         if (target_write_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), 0x3f) != ERROR_OK) {
226                                 LOG_ERROR("Register write failed");
227                                 return ERROR_FAIL;
228                         }
229
230                         if (target_write_u32(target, FLASH_REG_ADDRESS(bluenrgx_info),
231                                                                         (address - FLASH_BASE(bluenrgx_info)) >> 2) != ERROR_OK) {
232                                 LOG_ERROR("Register write failed");
233                                 return ERROR_FAIL;
234                         }
235
236                         if (target_write_u32(target, FLASH_REG_COMMAND(bluenrgx_info), command) != ERROR_OK) {
237                                 LOG_ERROR("Failed");
238                                 return ERROR_FAIL;
239                         }
240
241                         for (int j = 0; j < 100; j++) {
242                                 uint32_t value;
243                                 if (target_read_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), &value)) {
244                                         LOG_ERROR("Register write failed");
245                                         return ERROR_FAIL;
246                                 }
247                                 if (value & FLASH_INT_CMDDONE)
248                                         break;
249                                 if (j == 99) {
250                                         LOG_ERROR("Erase command failed (timeout)");
251                                         retval = ERROR_FAIL;
252                                 }
253                         }
254                 }
255         }
256
257         return retval;
258
259 }
260
261 static int bluenrgx_protect(struct flash_bank *bank, int set, int first, int last)
262 {
263         /* Protection is only handled in software: no hardware write protection
264            available in BlueNRG-x devices */
265         int sector;
266
267         for (sector = first; sector <= last; sector++)
268                 bank->sectors[sector].is_protected = set;
269         return ERROR_OK;
270 }
271
272 static int bluenrgx_write_word(struct flash_bank *bank, uint32_t address_base, uint8_t *values, uint32_t count)
273 {
274         int retval = ERROR_OK;
275         struct target *target =  bank->target;
276         struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;
277
278         retval = target_write_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), 0x3f);
279         if (retval != ERROR_OK) {
280                 LOG_ERROR("Register write failed, error code: %d", retval);
281                 return retval;
282         }
283
284         for (uint32_t i = 0; i < count; i++) {
285                 uint32_t address = address_base + i * FLASH_WORD_LEN;
286
287                 retval = target_write_u32(target, FLASH_REG_ADDRESS(bluenrgx_info),
288                                                                         (address - FLASH_BASE(bluenrgx_info)) >> 2);
289                 if (retval != ERROR_OK) {
290                         LOG_ERROR("Register write failed, error code: %d", retval);
291                         return retval;
292                 }
293
294                 retval = target_write_buffer(target, FLASH_REG_DATA(bluenrgx_info),
295                                                                                 FLASH_WORD_LEN, values + i * FLASH_WORD_LEN);
296                 if (retval != ERROR_OK) {
297                         LOG_ERROR("Register write failed, error code: %d", retval);
298                         return retval;
299                 }
300
301                 retval = target_write_u32(target, FLASH_REG_COMMAND(bluenrgx_info), FLASH_CMD_WRITE);
302                 if (retval != ERROR_OK) {
303                         LOG_ERROR("Register write failed, error code: %d", retval);
304                         return retval;
305                 }
306
307                 for (int j = 0; j < 100; j++) {
308                         uint32_t reg_value;
309                         retval = target_read_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), &reg_value);
310
311                         if (retval != ERROR_OK) {
312                                 LOG_ERROR("Register read failed, error code: %d", retval);
313                                 return retval;
314                         }
315
316                         if (reg_value & FLASH_INT_CMDDONE)
317                                 break;
318
319                         if (j == 99) {
320                                 LOG_ERROR("Write command failed (timeout)");
321                                 return ERROR_FAIL;
322                         }
323                 }
324         }
325         return retval;
326 }
327
328 static int bluenrgx_write_bytes(struct flash_bank *bank, uint32_t address_base, uint8_t *buffer, uint32_t count)
329 {
330         int retval = ERROR_OK;
331         struct target *target =  bank->target;
332         uint8_t *new_buffer = NULL;
333         uint32_t pre_bytes = 0, post_bytes = 0, pre_word, post_word, pre_address, post_address;
334
335         if (count == 0) {
336                 /* Just return if there are no bytes to write */
337                 return retval;
338         }
339
340         if (address_base & 3) {
341                 pre_bytes = address_base & 3;
342                 pre_address = address_base - pre_bytes;
343         }
344
345         if ((count + pre_bytes) & 3) {
346                 post_bytes = ((count + pre_bytes + 3) & ~3) - (count + pre_bytes);
347                 post_address = (address_base + count) & ~3;
348         }
349
350         if (pre_bytes || post_bytes) {
351                 uint32_t old_count = count;
352
353                 count = old_count + pre_bytes + post_bytes;
354
355                 new_buffer = malloc(count);
356
357                 if (new_buffer == NULL) {
358                         LOG_ERROR("odd number of bytes to write and no memory "
359                                   "for padding buffer");
360                         return ERROR_FAIL;
361                 }
362
363                 LOG_INFO("Requested number of bytes to write and/or address not word aligned (%" PRIu32 "), extending to %"
364                          PRIu32 " ", old_count, count);
365
366                 if (pre_bytes) {
367                         if (target_read_u32(target, pre_address, &pre_word)) {
368                                 LOG_ERROR("Memory read failed");
369                                 free(new_buffer);
370                                 return ERROR_FAIL;
371                         }
372
373                 }
374
375                 if (post_bytes) {
376                         if (target_read_u32(target, post_address, &post_word)) {
377                                 LOG_ERROR("Memory read failed");
378                                 free(new_buffer);
379                                 return ERROR_FAIL;
380                         }
381
382                 }
383
384                 memcpy(new_buffer, &pre_word, pre_bytes);
385                 memcpy((new_buffer+((pre_bytes+old_count) & ~3)), &post_word, 4);
386                 memcpy(new_buffer+pre_bytes, buffer, old_count);
387                 buffer = new_buffer;
388         }
389
390         retval = bluenrgx_write_word(bank, address_base - pre_bytes, buffer, count/4);
391
392         if (new_buffer)
393                 free(new_buffer);
394
395         return retval;
396 }
397
398 static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer,
399                           uint32_t offset, uint32_t count)
400 {
401         struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;
402         struct target *target = bank->target;
403         uint32_t buffer_size = 16384 + 8;
404         struct working_area *write_algorithm;
405         struct working_area *write_algorithm_sp;
406         struct working_area *source;
407         uint32_t address = bank->base + offset;
408         struct reg_param reg_params[5];
409         struct armv7m_algorithm armv7m_info;
410         int retval = ERROR_OK;
411         uint32_t pre_size = 0, fast_size = 0, post_size = 0;
412         uint32_t pre_offset = 0, fast_offset = 0, post_offset = 0;
413
414         /* check preconditions */
415         if (bluenrgx_info->probed == 0)
416                 return ERROR_FLASH_BANK_NOT_PROBED;
417
418         if ((offset + count) > bank->size) {
419                 LOG_ERROR("Requested write past beyond of flash size: (offset+count) = %d, size=%d",
420                           (offset + count),
421                           bank->size);
422                 return ERROR_FLASH_DST_OUT_OF_BANK;
423         }
424
425         if (bank->target->state != TARGET_HALTED) {
426                 LOG_ERROR("Target not halted");
427                 return ERROR_TARGET_NOT_HALTED;
428         }
429
430         /* We are good here and we need to compute pre_size, fast_size, post_size */
431         pre_size  = MIN(count, ((offset+0xF) & ~0xF) - offset);
432         pre_offset = offset;
433         fast_size = 16*((count - pre_size) / 16);
434         fast_offset = offset + pre_size;
435         post_size = (count-pre_size-fast_size) % 16;
436         post_offset = fast_offset + fast_size;
437
438         LOG_DEBUG("pre_size = %08x, pre_offset=%08x", pre_size, pre_offset);
439         LOG_DEBUG("fast_size = %08x, fast_offset=%08x", fast_size, fast_offset);
440         LOG_DEBUG("post_size = %08x, post_offset=%08x", post_size, post_offset);
441
442         /* Program initial chunk not 16 bytes aligned */
443         retval = bluenrgx_write_bytes(bank, bank->base+pre_offset, (uint8_t *) buffer, pre_size);
444         if (retval) {
445                 LOG_ERROR("bluenrgx_write_bytes failed %d", retval);
446                 return ERROR_FAIL;
447         }
448
449         /* Program chunk 16 bytes aligned in fast mode */
450         if (fast_size) {
451
452                 if (target_alloc_working_area(target, bluenrgx_info->flash_write_code_size,
453                                                   &write_algorithm) != ERROR_OK) {
454                         LOG_WARNING("no working area available, can't do block memory writes");
455                         return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
456                 }
457
458                 retval = target_write_buffer(target, write_algorithm->address,
459                                                  bluenrgx_info->flash_write_code_size,
460                                                  bluenrgx_info->flash_write_code);
461                 if (retval != ERROR_OK)
462                         return retval;
463
464                 /* memory buffer */
465                 if (target_alloc_working_area(target, buffer_size, &source)) {
466                         LOG_WARNING("no large enough working area available");
467                         return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
468                 }
469
470                 /* Stack pointer area */
471                 if (target_alloc_working_area(target, 64,
472                                                   &write_algorithm_sp) != ERROR_OK) {
473                         LOG_DEBUG("no working area for write code stack pointer");
474                         return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
475                 }
476
477                 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
478                 armv7m_info.core_mode = ARM_MODE_THREAD;
479
480                 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
481                 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
482                 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
483                 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
484                 init_reg_param(&reg_params[4], "sp", 32, PARAM_OUT);
485
486                 /* FIFO start address (first two words used for write and read pointers) */
487                 buf_set_u32(reg_params[0].value, 0, 32, source->address);
488                 /* FIFO end address (first two words used for write and read pointers) */
489                 buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);
490                 /* Flash memory address */
491                 buf_set_u32(reg_params[2].value, 0, 32, address+pre_size);
492                 /* Number of bytes */
493                 buf_set_u32(reg_params[3].value, 0, 32, fast_size);
494                 /* Stack pointer for program working area */
495                 buf_set_u32(reg_params[4].value, 0, 32, write_algorithm_sp->address);
496
497                 LOG_DEBUG("source->address = " TARGET_ADDR_FMT, source->address);
498                 LOG_DEBUG("source->address+ source->size = " TARGET_ADDR_FMT, source->address+source->size);
499                 LOG_DEBUG("write_algorithm_sp->address = " TARGET_ADDR_FMT, write_algorithm_sp->address);
500                 LOG_DEBUG("address = %08x", address+pre_size);
501                 LOG_DEBUG("count = %08x", count);
502
503                 retval = target_run_flash_async_algorithm(target,
504                                                           buffer+pre_size,
505                                                           fast_size/16,
506                                                           16, /* Block size: we write in block of 16 bytes to enjoy burstwrite speed */
507                                                           0,
508                                                           NULL,
509                                                           5,
510                                                           reg_params,
511                                                           source->address,
512                                                           source->size,
513                                                           write_algorithm->address,
514                                                           0,
515                                                           &armv7m_info);
516
517                 if (retval == ERROR_FLASH_OPERATION_FAILED) {
518                         LOG_ERROR("error executing bluenrg-x flash write algorithm");
519
520                         uint32_t error = buf_get_u32(reg_params[0].value, 0, 32);
521
522                         if (error != 0)
523                                 LOG_ERROR("flash write failed = %08" PRIx32, error);
524                 }
525                 if (retval == ERROR_OK) {
526                         uint32_t rp;
527                         /* Read back rp and check that is valid */
528                         retval = target_read_u32(target, source->address+4, &rp);
529                         if (retval == ERROR_OK) {
530                                 if ((rp < source->address+8) || (rp > (source->address + source->size))) {
531                                         LOG_ERROR("flash write failed = %08" PRIx32, rp);
532                                         retval = ERROR_FLASH_OPERATION_FAILED;
533                                 }
534                         }
535                 }
536                 target_free_working_area(target, source);
537                 target_free_working_area(target, write_algorithm);
538                 target_free_working_area(target, write_algorithm_sp);
539
540                 destroy_reg_param(&reg_params[0]);
541                 destroy_reg_param(&reg_params[1]);
542                 destroy_reg_param(&reg_params[2]);
543                 destroy_reg_param(&reg_params[3]);
544                 destroy_reg_param(&reg_params[4]);
545                 if (retval != ERROR_OK)
546                         return retval;
547
548         }
549
550         /* Program chunk at end, not addressable by fast burst write algorithm */
551         retval = bluenrgx_write_bytes(bank, bank->base+post_offset,
552                                                                          (uint8_t *) (buffer+pre_size+fast_size), post_size);
553         if (retval) {
554                 LOG_ERROR("bluenrgx_write_bytes failed %d", retval);
555                 return ERROR_FAIL;
556         }
557         return retval;
558 }
559
560 static int bluenrgx_probe(struct flash_bank *bank)
561 {
562         struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;
563         uint32_t idcode, size_info, die_id;
564         int i;
565         int retval = target_read_u32(bank->target, BLUENRGLP_JTAG_REG, &idcode);
566
567         if (retval != ERROR_OK)
568                 return retval;
569
570         if (idcode != BLUENRGLP_IDCODE) {
571                 retval = target_read_u32(bank->target, BLUENRG2_JTAG_REG, &idcode);
572                 if (retval != ERROR_OK)
573                         return retval;
574         }
575
576         /* Default device is BlueNRG-1 */
577         bluenrgx_info->flash_ptr = &flash_priv_data_1;
578         bluenrgx_info->flash_write_code = flash_priv_data_1.flash_write_code;
579         bluenrgx_info->flash_write_code_size = flash_priv_data_1.flash_write_code_size;
580
581         for (i = 0; i < (int)(sizeof(flash_ctrl)/sizeof(*flash_ctrl)); i++) {
582                 if (idcode == (*flash_ctrl[i]).jtag_idcode) {
583                         bluenrgx_info->flash_ptr = flash_ctrl[i];
584                         bluenrgx_info->flash_write_code = (*flash_ctrl[i]).flash_write_code;
585                         bluenrgx_info->flash_write_code_size = (*flash_ctrl[i]).flash_write_code_size;
586                         break;
587                 }
588         }
589
590         retval = target_read_u32(bank->target, FLASH_SIZE_REG(bluenrgx_info), &size_info);
591         if (retval != ERROR_OK)
592                 return retval;
593
594         retval = target_read_u32(bank->target, DIE_ID_REG(bluenrgx_info), &die_id);
595         if (retval != ERROR_OK)
596                 return retval;
597
598         bank->size = (size_info + 1) * FLASH_WORD_LEN;
599         bank->base = FLASH_BASE(bluenrgx_info);
600         bank->num_sectors = bank->size/FLASH_PAGE_SIZE(bluenrgx_info);
601         bank->sectors = realloc(bank->sectors, sizeof(struct flash_sector) * bank->num_sectors);
602
603         for (i = 0; i < bank->num_sectors; i++) {
604                 bank->sectors[i].offset = i * FLASH_PAGE_SIZE(bluenrgx_info);
605                 bank->sectors[i].size = FLASH_PAGE_SIZE(bluenrgx_info);
606                 bank->sectors[i].is_erased = -1;
607                 bank->sectors[i].is_protected = 0;
608         }
609
610         bluenrgx_info->probed = 1;
611         bluenrgx_info->die_id = die_id;
612
613         return ERROR_OK;
614 }
615
616 static int bluenrgx_auto_probe(struct flash_bank *bank)
617 {
618         struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;
619
620         if (bluenrgx_info->probed)
621                 return ERROR_OK;
622
623         return bluenrgx_probe(bank);
624 }
625
626 /* This method must return a string displaying information about the bank */
627 static int bluenrgx_get_info(struct flash_bank *bank, char *buf, int buf_size)
628 {
629         struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;
630         int mask_number, cut_number;
631
632         if (!bluenrgx_info->probed) {
633                 int retval = bluenrgx_probe(bank);
634                 if (retval != ERROR_OK) {
635                         snprintf(buf, buf_size,
636                                  "Unable to find bank information.");
637                         return retval;
638                 }
639         }
640
641         mask_number = (bluenrgx_info->die_id >> 4) & 0xF;
642         cut_number = bluenrgx_info->die_id & 0xF;
643
644         snprintf(buf, buf_size,
645                  "%s - Rev: %d.%d", bluenrgx_info->flash_ptr->part_name, mask_number, cut_number);
646         return ERROR_OK;
647 }
648
649 const struct flash_driver bluenrgx_flash = {
650         .name = "bluenrg-x",
651         .flash_bank_command = bluenrgx_flash_bank_command,
652         .erase = bluenrgx_erase,
653         .protect = bluenrgx_protect,
654         .write = bluenrgx_write,
655         .read = default_flash_read,
656         .probe = bluenrgx_probe,
657         .erase_check = default_flash_blank_check,
658         .protect_check = bluenrgx_protect_check,
659         .auto_probe = bluenrgx_auto_probe,
660         .info = bluenrgx_get_info,
661 };