at91sam3.c 58.3 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/***************************************************************************
 *   Copyright (C) 2009 by Duane Ellis                                     *
 *   openocd@duaneellis.com                                                *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS for A PARTICULAR PURPOSE.  See the         *
 *   GNU General public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
****************************************************************************/

/* Some of the the lower level code was based on code supplied by
 * ATMEL under this copyright. */

/* BEGIN ATMEL COPYRIGHT */
/* ----------------------------------------------------------------------------
26
 *         ATMEL Microcontroller Software Support
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
 * ----------------------------------------------------------------------------
 * Copyright (c) 2009, Atmel Corporation
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the disclaimer below.
 *
 * Atmel's name may not be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ----------------------------------------------------------------------------
 */
/* END ATMEL COPYRIGHT */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif


Zachary T Welch's avatar
Zachary T Welch committed
60
#include "imp.h"
61
#include "at91sam3.h"
Zachary T Welch's avatar
Zachary T Welch committed
62
#include <helper/membuf.h>
63
#include <helper/time_support.h>
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

#define REG_NAME_WIDTH  (12)


#define FLASH_BANK0_BASE   0x00080000
#define FLASH_BANK1_BASE   0x00100000

#define 	AT91C_EFC_FCMD_GETD                 (0x0) // (EFC) Get Flash Descriptor
#define 	AT91C_EFC_FCMD_WP                   (0x1) // (EFC) Write Page
#define 	AT91C_EFC_FCMD_WPL                  (0x2) // (EFC) Write Page and Lock
#define 	AT91C_EFC_FCMD_EWP                  (0x3) // (EFC) Erase Page and Write Page
#define 	AT91C_EFC_FCMD_EWPL                 (0x4) // (EFC) Erase Page and Write Page then Lock
#define 	AT91C_EFC_FCMD_EA                   (0x5) // (EFC) Erase All
// cmd6 is not present int he at91sam3u4/2/1 data sheet table 17-2
// #define 	AT91C_EFC_FCMD_EPL                  (0x6) // (EFC) Erase plane?
// cmd7 is not present int he at91sam3u4/2/1 data sheet table 17-2
// #define 	AT91C_EFC_FCMD_EPA                  (0x7) // (EFC) Erase pages?
#define 	AT91C_EFC_FCMD_SLB                  (0x8) // (EFC) Set Lock Bit
#define 	AT91C_EFC_FCMD_CLB                  (0x9) // (EFC) Clear Lock Bit
#define 	AT91C_EFC_FCMD_GLB                  (0xA) // (EFC) Get Lock Bit
#define 	AT91C_EFC_FCMD_SFB                  (0xB) // (EFC) Set Fuse Bit
#define 	AT91C_EFC_FCMD_CFB                  (0xC) // (EFC) Clear Fuse Bit
#define 	AT91C_EFC_FCMD_GFB                  (0xD) // (EFC) Get Fuse Bit
#define 	AT91C_EFC_FCMD_STUI                 (0xE) // (EFC) Start Read Unique ID
#define 	AT91C_EFC_FCMD_SPUI                 (0xF) // (EFC) Stop Read Unique ID

#define  offset_EFC_FMR   0
#define  offset_EFC_FCR   4
#define  offset_EFC_FSR   8
#define  offset_EFC_FRR   12


static float
97
_tomhz(uint32_t freq_hz)
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
{
	float f;

	f = ((float)(freq_hz)) / 1000000.0;
	return f;
}

// How the chip is configured.
struct sam3_cfg {
	uint32_t unique_id[4];

	uint32_t slow_freq;
	uint32_t rc_freq;
	uint32_t mainosc_freq;
	uint32_t plla_freq;
	uint32_t mclk_freq;
	uint32_t cpu_freq;
	uint32_t fclk_freq;
	uint32_t pclk0_freq;
	uint32_t pclk1_freq;
	uint32_t pclk2_freq;


#define SAM3_CHIPID_CIDR          (0x400E0740)
	uint32_t CHIPID_CIDR;
#define SAM3_CHIPID_EXID          (0x400E0744)
	uint32_t CHIPID_EXID;

#define SAM3_SUPC_CR              (0x400E1210)
127
	uint32_t SUPC_CR;
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

#define SAM3_PMC_BASE             (0x400E0400)
#define SAM3_PMC_SCSR             (SAM3_PMC_BASE + 0x0008)
	uint32_t PMC_SCSR;
#define SAM3_PMC_PCSR             (SAM3_PMC_BASE + 0x0018)
	uint32_t PMC_PCSR;
#define SAM3_CKGR_UCKR            (SAM3_PMC_BASE + 0x001c)
	uint32_t CKGR_UCKR;
#define SAM3_CKGR_MOR             (SAM3_PMC_BASE + 0x0020)
	uint32_t CKGR_MOR;
#define SAM3_CKGR_MCFR            (SAM3_PMC_BASE + 0x0024)
	uint32_t CKGR_MCFR;
#define SAM3_CKGR_PLLAR           (SAM3_PMC_BASE + 0x0028)
	uint32_t CKGR_PLLAR;
#define SAM3_PMC_MCKR             (SAM3_PMC_BASE + 0x0030)
	uint32_t PMC_MCKR;
#define SAM3_PMC_PCK0             (SAM3_PMC_BASE + 0x0040)
	uint32_t PMC_PCK0;
#define SAM3_PMC_PCK1             (SAM3_PMC_BASE + 0x0044)
	uint32_t PMC_PCK1;
#define SAM3_PMC_PCK2             (SAM3_PMC_BASE + 0x0048)
	uint32_t PMC_PCK2;
#define SAM3_PMC_SR               (SAM3_PMC_BASE + 0x0068)
	uint32_t PMC_SR;
#define SAM3_PMC_IMR              (SAM3_PMC_BASE + 0x006c)
	uint32_t PMC_IMR;
#define SAM3_PMC_FSMR             (SAM3_PMC_BASE + 0x0070)
	uint32_t PMC_FSMR;
#define SAM3_PMC_FSPR             (SAM3_PMC_BASE + 0x0074)
	uint32_t PMC_FSPR;
};


struct sam3_bank_private {
	int probed;
	// DANGER: THERE ARE DRAGONS HERE..
	// NOTE: If you add more 'ghost' pointers
165
	// be aware that you must *manually* update
166
167
168
169
170
	// these pointers in the function sam3_GetDetails()
	// See the comment "Here there be dragons"

	// so we can find the chip we belong to
	struct sam3_chip *pChip;
171
	// so we can find the orginal bank pointer
172
	struct flash_bank *pBank;
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
	unsigned bank_number;
	uint32_t controller_address;
	uint32_t base_address;
	bool present;
	unsigned size_bytes;
	unsigned nsectors;
	unsigned sector_size;
	unsigned page_size;
};

struct sam3_chip_details {
	// THERE ARE DRAGONS HERE..
	// note: If you add pointers here
	// becareful about them as they
	// may need to be updated inside
	// the function: "sam3_GetDetails()
	// which copy/overwrites the
	// 'runtime' copy of this structure
	uint32_t chipid_cidr;
	const char *name;

	unsigned n_gpnvms;
#define SAM3_N_NVM_BITS 3
	unsigned  gpnvm[SAM3_N_NVM_BITS];
	unsigned  total_flash_size;
	unsigned  total_sram_size;
	unsigned  n_banks;
#define SAM3_MAX_FLASH_BANKS 2
	// these are "initialized" from the global const data
	struct sam3_bank_private bank[SAM3_MAX_FLASH_BANKS];
};


struct sam3_chip {
	struct sam3_chip *next;
	int    probed;

	// this is "initialized" from the global const structure
	struct sam3_chip_details details;
Zachary T Welch's avatar
Zachary T Welch committed
212
	struct target *target;
213
214
215
216
217
218
219
220
	struct sam3_cfg cfg;

	struct membuf *mbuf;
};


struct sam3_reg_list {
	uint32_t address;  size_t struct_offset; const char *name;
221
	void (*explain_func)(struct sam3_chip *pInfo);
222
223
224
225
226
227
};


static struct sam3_chip *all_sam3_chips;

static struct sam3_chip *
228
get_current_sam3(struct command_context *cmd_ctx)
229
{
Zachary T Welch's avatar
Zachary T Welch committed
230
	struct target *t;
231
232
	static struct sam3_chip *p;

233
	t = get_current_target(cmd_ctx);
zwelch's avatar
zwelch committed
234
	if (!t) {
235
		command_print(cmd_ctx, "No current target?");
236
237
238
239
		return NULL;
	}

	p = all_sam3_chips;
zwelch's avatar
zwelch committed
240
	if (!p) {
241
242
		// this should not happen
		// the command is not registered until the chip is created?
243
		command_print(cmd_ctx, "No SAM3 chips exist?");
244
245
246
		return NULL;
	}

zwelch's avatar
zwelch committed
247
248
	while (p) {
		if (p->target == t) {
249
250
251
252
			return p;
		}
		p = p->next;
	}
253
	command_print(cmd_ctx, "Cannot find SAM3 chip?");
254
255
256
257
258
259
260
261
262
263
264
	return NULL;
}


// these are used to *initialize* the "pChip->details" structure.
static const struct sam3_chip_details all_sam3_details[] = {
	{
		.chipid_cidr    = 0x28100960,
		.name           = "at91sam3u4e",
		.total_flash_size     = 256 * 1024,
		.total_sram_size      = 52 * 1024,
265
		.n_gpnvms       = 3,
266
267
268
269
270
271
		.n_banks        = 2,

		// System boots at address 0x0
		// gpnvm[1] = selects boot code
		//     if gpnvm[1] == 0
		//         boot is via "SAMBA" (rom)
272
		//     else
273
274
275
276
277
278
279
280
281
282
		//         boot is via FLASH
		//         Selection is via gpnvm[2]
		//     endif
		//
		// NOTE: banks 0 & 1 switch places
		//     if gpnvm[2] == 0
		//         Bank0 is the boot rom
		//      else
		//         Bank1 is the boot rom
		//      endif
283
284
285
//		.bank[0] = {
		{
		  {
286
287
288
289
			.probed = 0,
			.pChip  = NULL,
			.pBank  = NULL,
			.bank_number = 0,
290
			.base_address = FLASH_BANK0_BASE,
291
292
293
294
295
296
			.controller_address = 0x400e0800,
			.present = 1,
			.size_bytes = 128 * 1024,
			.nsectors   = 16,
			.sector_size = 8192,
			.page_size   = 256,
297
		  },
298

299
300
//		.bank[1] = {
		  {
301
302
303
304
305
306
307
308
309
310
311
			.probed = 0,
			.pChip  = NULL,
			.pBank  = NULL,
			.bank_number = 1,
			.base_address = FLASH_BANK1_BASE,
			.controller_address = 0x400e0a00,
			.present = 1,
			.size_bytes = 128 * 1024,
			.nsectors   = 16,
			.sector_size = 8192,
			.page_size   = 256,
312
		  },
313
314
315
316
317
318
319
320
		},
	},

	{
		.chipid_cidr    = 0x281a0760,
		.name           = "at91sam3u2e",
		.total_flash_size     = 128 * 1024,
		.total_sram_size      =  36 * 1024,
321
		.n_gpnvms       = 2,
322
323
324
325
326
327
		.n_banks        = 1,

		// System boots at address 0x0
		// gpnvm[1] = selects boot code
		//     if gpnvm[1] == 0
		//         boot is via "SAMBA" (rom)
328
		//     else
329
330
331
		//         boot is via FLASH
		//         Selection is via gpnvm[2]
		//     endif
332
333
334
//		.bank[0] = {
		{
		  {
335
336
337
338
			.probed = 0,
			.pChip  = NULL,
			.pBank  = NULL,
			.bank_number = 0,
339
			.base_address = FLASH_BANK0_BASE,
340
341
342
343
344
345
			.controller_address = 0x400e0800,
			.present = 1,
			.size_bytes = 128 * 1024,
			.nsectors   = 16,
			.sector_size = 8192,
			.page_size   = 256,
346
347
348
		  },
//		  .bank[1] = {
		  {
349
350
351
			.present = 0,
			.probed = 0,
			.bank_number = 1,
352
		  },
353
354
355
356
357
358
359
		},
	},
	{
		.chipid_cidr    = 0x28190560,
		.name           = "at91sam3u1e",
		.total_flash_size     = 64 * 1024,
		.total_sram_size      = 20 * 1024,
360
		.n_gpnvms       = 2,
361
362
363
364
365
366
		.n_banks        = 1,

		// System boots at address 0x0
		// gpnvm[1] = selects boot code
		//     if gpnvm[1] == 0
		//         boot is via "SAMBA" (rom)
367
		//     else
368
369
370
371
		//         boot is via FLASH
		//         Selection is via gpnvm[2]
		//     endif
		//
372

373
374
375
//		.bank[0] = {
		{
		  {
376
377
378
379
			.probed = 0,
			.pChip  = NULL,
			.pBank  = NULL,
			.bank_number = 0,
380
			.base_address = FLASH_BANK0_BASE,
381
382
383
384
385
386
			.controller_address = 0x400e0800,
			.present = 1,
			.size_bytes =  64 * 1024,
			.nsectors   =  8,
			.sector_size = 8192,
			.page_size   = 256,
387
		  },
388

389
390
//		.bank[1] = {
		  {
391
392
393
			.present = 0,
			.probed = 0,
			.bank_number = 1,
394
		  },
395
396
		},
	},
397

398
399
400
401
402
	{
		.chipid_cidr    = 0x28000960,
		.name           = "at91sam3u4c",
		.total_flash_size     = 256 * 1024,
		.total_sram_size      = 52 * 1024,
403
		.n_gpnvms       = 3,
404
405
406
407
408
409
		.n_banks        = 2,

		// System boots at address 0x0
		// gpnvm[1] = selects boot code
		//     if gpnvm[1] == 0
		//         boot is via "SAMBA" (rom)
410
		//     else
411
412
413
414
415
416
417
418
419
420
		//         boot is via FLASH
		//         Selection is via gpnvm[2]
		//     endif
		//
		// NOTE: banks 0 & 1 switch places
		//     if gpnvm[2] == 0
		//         Bank0 is the boot rom
		//      else
		//         Bank1 is the boot rom
		//      endif
421
422
423
		{
		  {
//		.bank[0] = {
424
425
426
427
			.probed = 0,
			.pChip  = NULL,
			.pBank  = NULL,
			.bank_number = 0,
428
			.base_address = FLASH_BANK0_BASE,
429
430
431
432
433
434
			.controller_address = 0x400e0800,
			.present = 1,
			.size_bytes = 128 * 1024,
			.nsectors   = 16,
			.sector_size = 8192,
			.page_size   = 256,
435
436
437
		  },
//		.bank[1] = {
		  {
438
439
440
441
442
443
444
445
446
447
448
			.probed = 0,
			.pChip  = NULL,
			.pBank  = NULL,
			.bank_number = 1,
			.base_address = FLASH_BANK1_BASE,
			.controller_address = 0x400e0a00,
			.present = 1,
			.size_bytes = 128 * 1024,
			.nsectors   = 16,
			.sector_size = 8192,
			.page_size   = 256,
449
		  },
450
451
452
453
454
455
456
457
		},
	},

	{
		.chipid_cidr    = 0x280a0760,
		.name           = "at91sam3u2c",
		.total_flash_size     = 128 * 1024,
		.total_sram_size      = 36 * 1024,
458
		.n_gpnvms       = 2,
459
460
461
462
463
464
		.n_banks        = 1,

		// System boots at address 0x0
		// gpnvm[1] = selects boot code
		//     if gpnvm[1] == 0
		//         boot is via "SAMBA" (rom)
465
		//     else
466
467
468
		//         boot is via FLASH
		//         Selection is via gpnvm[2]
		//     endif
469
470
471
		{
//		.bank[0] = {
		  {
472
473
474
475
			.probed = 0,
			.pChip  = NULL,
			.pBank  = NULL,
			.bank_number = 0,
476
			.base_address = FLASH_BANK0_BASE,
477
478
479
480
481
482
			.controller_address = 0x400e0800,
			.present = 1,
			.size_bytes = 128 * 1024,
			.nsectors   = 16,
			.sector_size = 8192,
			.page_size   = 256,
483
484
485
		  },
//		.bank[1] = {
		  {
486
487
488
			.present = 0,
			.probed = 0,
			.bank_number = 1,
489
		  },
490
491
492
493
494
495
496
		},
	},
	{
		.chipid_cidr    = 0x28090560,
		.name           = "at91sam3u1c",
		.total_flash_size     = 64 * 1024,
		.total_sram_size      = 20 * 1024,
497
		.n_gpnvms       = 2,
498
499
500
501
502
503
		.n_banks        = 1,

		// System boots at address 0x0
		// gpnvm[1] = selects boot code
		//     if gpnvm[1] == 0
		//         boot is via "SAMBA" (rom)
504
		//     else
505
506
507
508
		//         boot is via FLASH
		//         Selection is via gpnvm[2]
		//     endif
		//
509

510
511
512
		{
//		.bank[0] = {
		  {
513
514
515
516
			.probed = 0,
			.pChip  = NULL,
			.pBank  = NULL,
			.bank_number = 0,
517
			.base_address = FLASH_BANK0_BASE,
518
519
520
521
522
523
			.controller_address = 0x400e0800,
			.present = 1,
			.size_bytes =  64 * 1024,
			.nsectors   =  8,
			.sector_size = 8192,
			.page_size   = 256,
524
525
526
		  },
//		.bank[1] = {
		  {
527
528
529
			.present = 0,
			.probed = 0,
			.bank_number = 1,
530
531

		  },
532
533
534
535
		},
	},

	// terminate
536
	{
537
538
539
540
541
542
543
544
545
546
547
548
549
550
		.chipid_cidr	= 0,
		.name			= NULL,
	}
};

/* Globals above */
/***********************************************************************
 **********************************************************************
 **********************************************************************
 **********************************************************************
 **********************************************************************
 **********************************************************************/
/* *ATMEL* style code - from the SAM3 driver code */

551
552
/**
 * Get the current status of the EEFC and
553
554
555
556
 * the value of some status bits (LOCKE, PROGE).
 * @param pPrivate - info about the bank
 * @param v        - result goes here
 */
557
static int
558
EFC_GetStatus(struct sam3_bank_private *pPrivate, uint32_t *v)
559
560
{
	int r;
561
	r = target_read_u32(pPrivate->pChip->target, pPrivate->controller_address + offset_EFC_FSR, v);
562
	LOG_DEBUG("Status: 0x%08x (lockerror: %d, cmderror: %d, ready: %d)",
563
564
565
566
			  (unsigned int)(*v),
			  ((unsigned int)((*v >> 2) & 1)),
			  ((unsigned int)((*v >> 1) & 1)),
			  ((unsigned int)((*v >> 0) & 1)));
567

568
569
570
	return r;
}

571
572
/**
 * Get the result of the last executed command.
573
574
575
 * @param pPrivate - info about the bank
 * @param v        - result goes here
 */
576
static int
577
EFC_GetResult(struct sam3_bank_private *pPrivate, uint32_t *v)
578
579
580
{
	int r;
	uint32_t rv;
581
	r = target_read_u32(pPrivate->pChip->target, pPrivate->controller_address + offset_EFC_FRR, &rv);
zwelch's avatar
zwelch committed
582
	if (v) {
583
584
585
586
587
588
589
590
		*v = rv;
	}
	LOG_DEBUG("Result: 0x%08x", ((unsigned int)(rv)));
	return r;
}

static int
EFC_StartCommand(struct sam3_bank_private *pPrivate,
591
				 unsigned command, unsigned argument)
592
593
594
595
596
597
598
599
600
601
602
603
604
{
	uint32_t n,v;
	int r;
	int retry;

	retry = 0;
 do_retry:

    // Check command & argument
    switch (command) {

	case AT91C_EFC_FCMD_WP:
	case AT91C_EFC_FCMD_WPL:
605
	case AT91C_EFC_FCMD_EWP:
606
607
608
609
610
611
	case AT91C_EFC_FCMD_EWPL:
		// case AT91C_EFC_FCMD_EPL:
		// case AT91C_EFC_FCMD_EPA:
	case AT91C_EFC_FCMD_SLB:
	case AT91C_EFC_FCMD_CLB:
		n = (pPrivate->size_bytes / pPrivate->page_size);
zwelch's avatar
zwelch committed
612
		if (argument >= n) {
613
614
615
			LOG_ERROR("*BUG*: Embedded flash has only %u pages", (unsigned)(n));
		}
		break;
616

617
618
	case AT91C_EFC_FCMD_SFB:
	case AT91C_EFC_FCMD_CFB:
zwelch's avatar
zwelch committed
619
		if (argument >= pPrivate->pChip->details.n_gpnvms) {
620
			LOG_ERROR("*BUG*: Embedded flash has only %d GPNVMs",
621
					  pPrivate->pChip->details.n_gpnvms);
622
623
		}
		break;
624

625
626
627
628
629
630
	case AT91C_EFC_FCMD_GETD:
	case AT91C_EFC_FCMD_EA:
	case AT91C_EFC_FCMD_GLB:
	case AT91C_EFC_FCMD_GFB:
	case AT91C_EFC_FCMD_STUI:
	case AT91C_EFC_FCMD_SPUI:
zwelch's avatar
zwelch committed
631
		if (argument != 0) {
632
			LOG_ERROR("Argument is meaningless for cmd: %d", command);
633
634
635
636
637
638
639
		}
		break;
	default:
		LOG_ERROR("Unknown command %d", command);
		break;
    }

zwelch's avatar
zwelch committed
640
	if (command == AT91C_EFC_FCMD_SPUI) {
641
642
643
644
645
646
		// this is a very special situation.
		// Situation (1) - error/retry - see below
		//      And we are being called recursively
		// Situation (2) - normal, finished reading unique id
	} else {
		// it should be "ready"
647
		EFC_GetStatus(pPrivate, &v);
zwelch's avatar
zwelch committed
648
		if (v & 1) {
649
650
651
			// then it is ready
			// we go on
		} else {
zwelch's avatar
zwelch committed
652
			if (retry) {
653
654
				// we have done this before
				// the controller is not responding.
655
				LOG_ERROR("flash controller(%d) is not ready! Error", pPrivate->bank_number);
656
657
658
				return ERROR_FAIL;
			} else {
				retry++;
659
				LOG_ERROR("Flash controller(%d) is not ready, attempting reset",
660
						  pPrivate->bank_number);
661
				// we do that by issuing the *STOP* command
662
				EFC_StartCommand(pPrivate, AT91C_EFC_FCMD_SPUI, 0);
663
				// above is recursive, and further recursion is blocked by
664
				// if (command == AT91C_EFC_FCMD_SPUI) above
665
666
667
668
669
670
				goto do_retry;
			}
		}
	}

	v = (0x5A << 24) | (argument << 8) | command;
671
	LOG_DEBUG("Command: 0x%08x", ((unsigned int)(v)));
672
	r = target_write_u32(pPrivate->pBank->target,
673
674
						  pPrivate->controller_address + offset_EFC_FCR,
						  v);
zwelch's avatar
zwelch committed
675
	if (r != ERROR_OK) {
676
677
678
679
680
		LOG_DEBUG("Error Write failed");
	}
	return r;
}

681
682
/**
 * Performs the given command and wait until its completion (or an error).
683
684
685
686
687
 * @param pPrivate - info about the bank
 * @param command  - Command to perform.
 * @param argument - Optional command argument.
 * @param status   - put command status bits here
 */
688
689
690
691
static int
EFC_PerformCommand(struct sam3_bank_private *pPrivate,
					unsigned command,
					unsigned argument,
692
693
694
695
696
697
698
					uint32_t *status)
{

	int r;
	uint32_t v;
	long long ms_now, ms_end;

699
	// default
zwelch's avatar
zwelch committed
700
	if (status) {
701
702
703
		*status = 0;
	}

704
	r = EFC_StartCommand(pPrivate, command, argument);
zwelch's avatar
zwelch committed
705
	if (r != ERROR_OK) {
706
707
708
709
710
711
712
		return r;
	}

	ms_end = 500 + timeval_ms();


    do {
713
		r = EFC_GetStatus(pPrivate, &v);
zwelch's avatar
zwelch committed
714
		if (r != ERROR_OK) {
715
716
717
			return r;
		}
		ms_now = timeval_ms();
zwelch's avatar
zwelch committed
718
		if (ms_now > ms_end) {
719
720
721
722
723
			// error
			LOG_ERROR("Command timeout");
			return ERROR_FAIL;
		}
    }
724
    while ((v & 1) == 0)
725
726
727
		;

	// error bits..
zwelch's avatar
zwelch committed
728
	if (status) {
729
730
731
732
733
734
735
736
737
738
		*status = (v & 0x6);
	}
	return ERROR_OK;

}





739
740
741
/**
 * Read the unique ID.
 * @param pPrivate - info about the bank
742
743
744
 * The unique ID is stored in the 'pPrivate' structure.
 */
static int
745
FLASHD_ReadUniqueID (struct sam3_bank_private *pPrivate)
746
747
748
749
750
751
752
753
754
755
756
{
	int r;
	uint32_t v;
	int x;
	// assume 0
    pPrivate->pChip->cfg.unique_id[0] = 0;
    pPrivate->pChip->cfg.unique_id[1] = 0;
    pPrivate->pChip->cfg.unique_id[2] = 0;
    pPrivate->pChip->cfg.unique_id[3] = 0;

	LOG_DEBUG("Begin");
757
	r = EFC_StartCommand(pPrivate, AT91C_EFC_FCMD_STUI, 0);
zwelch's avatar
zwelch committed
758
	if (r < 0) {
759
760
761
		return r;
	}

zwelch's avatar
zwelch committed
762
	for (x = 0 ; x < 4 ; x++) {
763
		r = target_read_u32(pPrivate->pChip->target,
764
							 pPrivate->pBank->base + (x * 4),
765
							 &v);
zwelch's avatar
zwelch committed
766
		if (r < 0) {
767
768
769
770
771
			return r;
		}
		pPrivate->pChip->cfg.unique_id[x] = v;
	}

772
    r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SPUI, 0, NULL);
zwelch's avatar
zwelch committed
773
	LOG_DEBUG("End: R=%d, id = 0x%08x, 0x%08x, 0x%08x, 0x%08x",
774
			  r,
775
776
777
778
779
			  (unsigned int)(pPrivate->pChip->cfg.unique_id[0]),
			  (unsigned int)(pPrivate->pChip->cfg.unique_id[1]),
			  (unsigned int)(pPrivate->pChip->cfg.unique_id[2]),
			  (unsigned int)(pPrivate->pChip->cfg.unique_id[3]));
	return r;
780

781
782
}

783
784
/**
 * Erases the entire flash.
785
786
787
 * @param pPrivate - the info about the bank.
 */
static int
788
FLASHD_EraseEntireBank(struct sam3_bank_private *pPrivate)
789
790
{
	LOG_DEBUG("Here");
791
	return EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_EA, 0, NULL);
792
793
794
795
}



796
797
/**
 * Gets current GPNVM state.
798
799
800
801
802
 * @param pPrivate - info about the bank.
 * @param gpnvm    -  GPNVM bit index.
 * @param puthere  - result stored here.
 */
//------------------------------------------------------------------------------
803
static int
804
FLASHD_GetGPNVM(struct sam3_bank_private *pPrivate, unsigned gpnvm, unsigned *puthere)
805
806
807
808
809
{
	uint32_t v;
	int r;

	LOG_DEBUG("Here");
zwelch's avatar
zwelch committed
810
	if (pPrivate->bank_number != 0) {
811
812
813
814
		LOG_ERROR("GPNVM only works with Bank0");
		return ERROR_FAIL;
	}

zwelch's avatar
zwelch committed
815
	if (gpnvm >= pPrivate->pChip->details.n_gpnvms) {
816
		LOG_ERROR("Invalid GPNVM %d, max: %d, ignored",
817
				  gpnvm,pPrivate->pChip->details.n_gpnvms);
818
819
820
821
		return ERROR_FAIL;
	}

    // Get GPNVMs status
822
	r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_GFB, 0, NULL);
zwelch's avatar
zwelch committed
823
	if (r != ERROR_OK) {
824
825
826
827
		LOG_ERROR("Failed");
		return r;
	}

828
    r = EFC_GetResult(pPrivate, &v);
829

zwelch's avatar
zwelch committed
830
	if (puthere) {
831
		// Check if GPNVM is set
832
		// get the bit and make it a 0/1
833
834
835
836
837
838
839
840
841
		*puthere = (v >> gpnvm) & 1;
	}

	return r;
}




842
843
844
845
846
/**
 * Clears the selected GPNVM bit.
 * @param pPrivate info about the bank
 * @param gpnvm GPNVM index.
 * @returns 0 if successful; otherwise returns an error code.
847
 */
848
static int
849
FLASHD_ClrGPNVM(struct sam3_bank_private *pPrivate, unsigned gpnvm)
850
851
852
853
854
{
	int r;
	unsigned v;

	LOG_DEBUG("Here");
zwelch's avatar
zwelch committed
855
	if (pPrivate->bank_number != 0) {
856
857
858
859
		LOG_ERROR("GPNVM only works with Bank0");
		return ERROR_FAIL;
	}

zwelch's avatar
zwelch committed
860
	if (gpnvm >= pPrivate->pChip->details.n_gpnvms) {
861
		LOG_ERROR("Invalid GPNVM %d, max: %d, ignored",
862
				  gpnvm,pPrivate->pChip->details.n_gpnvms);
863
864
865
		return ERROR_FAIL;
	}

866
	r = FLASHD_GetGPNVM(pPrivate, gpnvm, &v);
zwelch's avatar
zwelch committed
867
	if (r != ERROR_OK) {
868
869
870
		LOG_DEBUG("Failed: %d",r);
		return r;
	}
871
	r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_CFB, gpnvm, NULL);
872
873
874
875
876
877
	LOG_DEBUG("End: %d",r);
	return r;
}



878
879
880
881
/**
 * Sets the selected GPNVM bit.
 * @param pPrivate info about the bank
 * @param gpnvm GPNVM index.
882
 */
883
static int
884
FLASHD_SetGPNVM(struct sam3_bank_private *pPrivate, unsigned gpnvm)
885
886
887
888
{
	int r;
	unsigned v;

zwelch's avatar
zwelch committed
889
	if (pPrivate->bank_number != 0) {
890
891
892
893
		LOG_ERROR("GPNVM only works with Bank0");
		return ERROR_FAIL;
	}

zwelch's avatar
zwelch committed
894
	if (gpnvm >= pPrivate->pChip->details.n_gpnvms) {
895
		LOG_ERROR("Invalid GPNVM %d, max: %d, ignored",
896
				  gpnvm,pPrivate->pChip->details.n_gpnvms);
897
898
899
		return ERROR_FAIL;
	}

900
	r = FLASHD_GetGPNVM(pPrivate, gpnvm, &v);
zwelch's avatar
zwelch committed
901
	if (r != ERROR_OK) {
902
903
		return r;
	}
zwelch's avatar
zwelch committed
904
	if (v) {
905
906
907
908
		// already set
		r = ERROR_OK;
	} else {
		// set it
909
		r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SFB, gpnvm, NULL);
910
911
912
913
914
	}
	return r;
}


915
916
917
918
/**
 * Returns a bit field (at most 64) of locked regions within a page.
 * @param pPrivate info about the bank
 * @param v where to store locked bits
919
 */
920
static int
921
FLASHD_GetLockBits(struct sam3_bank_private *pPrivate, uint32_t *v)
922
923
924
{
	int r;
	LOG_DEBUG("Here");
925
    r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_GLB, 0, NULL);
zwelch's avatar
zwelch committed
926
	if (r == ERROR_OK) {
927
		r = EFC_GetResult(pPrivate, v);
928
929
930
931
932
933
	}
	LOG_DEBUG("End: %d",r);
	return r;
}


934
935
936
937
938
/**
 * Unlocks all the regions in the given address range.
 * @param pPrivate info about the bank
 * @param start_sector first sector to unlock
 * @param end_sector last (inclusive) to unlock
939
940
941
 */

static int
942
FLASHD_Unlock(struct sam3_bank_private *pPrivate,
943
			   unsigned start_sector,
944
			   unsigned end_sector)
945
946
947
948
949
950
951
952
953
{
	int r;
	uint32_t status;
	uint32_t pg;
	uint32_t pages_per_sector;

	pages_per_sector = pPrivate->sector_size / pPrivate->page_size;

    /* Unlock all pages */
zwelch's avatar
zwelch committed
954
    while (start_sector <= end_sector) {
955
956
		pg = start_sector * pages_per_sector;

957
        r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_CLB, pg, &status);
958
959
960
961
962
963
964
965
966
967
        if (r != ERROR_OK) {
            return r;
        }
        start_sector++;
    }

    return ERROR_OK;
}


968
969
970
/**
 * Locks regions
 * @param pPrivate - info about the bank
971
972
973
 * @param start_sector - first sector to lock
 * @param end_sector   - last sector (inclusive) to lock
 */
974
static int
975
FLASHD_Lock(struct sam3_bank_private *pPrivate,
976
			 unsigned start_sector,
977
			 unsigned end_sector)
978
979
980
981
982
983
984
{
	uint32_t status;
	uint32_t pg;
	uint32_t pages_per_sector;
	int r;

	pages_per_sector = pPrivate->sector_size / pPrivate->page_size;
985

986
    /* Lock all pages */
zwelch's avatar
zwelch committed
987
    while (start_sector <= end_sector) {
988
989
		pg = start_sector * pages_per_sector;

990
        r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SLB, pg, &status);
991
992
993
994
995
996
997
998
999
1000
        if (r != ERROR_OK) {
            return r;
        }
        start_sector++;
    }
    return ERROR_OK;
}


/****** END SAM3 CODE ********/
For faster browsing, not all history is shown. View entire blame