summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/shared/flash/flashPgmPvt.h
blob: 52825d0c5a3edfc47fe7efc7df309743f21b3728 (plain) (blame)
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
26
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
60
61
62
63
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
97
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
127
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
165
166
167
168
169
170
171
172
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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
#ifndef FLASH_GLUE_INTERFACE_H
#define FLASH_GLUE_INTERFACE_H


/* Trivial flash programmer (for restrictions see below)     */

/* Author: Till Straumann <strauman@slac.stanford.edu>, 2006 */

/* DO NOT INCLUDE THIS HEADER FROM APPLICATION CODE          */

/*
 * Glue interface -- to be used only internally by BSP
 * and chip drivers:
 * - BSP provides info about what chip drivers to use
 *   as well as 'wiring' info (how many devices are
 *   operated in parallel etc).
 * - Chip drivers provide low-level 'methods' / 'ops'
 *   for performing basic operations which are used
 *   by the code in 'flash.c'.
 */

/* To keep things simple, this API makes a few assumptions about the
 * hardware:
 *
 * - devices operate with 16-bit data width
 * - two devices are used in parallel (stride 4) to
 *   provide 32-bit data. I.e., the devices are
 *   organized like this:
 *   unsigned short flash[FLASH_SIZE][2];
 * - no endianness issues (i.e., flash endianness ==  CPU endianness)
 * - fixed block size
 * - fixed buffer size
 * - all devices in a bank are identical
 * - NOT THREAD SAFE; no locking scheme is implemented.
 * - cannot copy within same flash bank.
 * - write-timeout uses polling/busy-wait
 *
 * FIXME: code should be revised to remove assumptions on stride and 16-bit
 *        width to make it more generic.
 */

/*
 * Authorship
 * ----------
 * This software was created by
 *     Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
 * 	   Stanford Linear Accelerator Center, Stanford University.
 *
 * Acknowledgement of sponsorship
 * ------------------------------
 * The software was produced by
 *     the Stanford Linear Accelerator Center, Stanford University,
 * 	   under Contract DE-AC03-76SFO0515 with the Department of Energy.
 *
 * Government disclaimer of liability
 * ----------------------------------
 * Neither the United States nor the United States Department of Energy,
 * nor any of their employees, makes any warranty, express or implied, or
 * assumes any legal liability or responsibility for the accuracy,
 * completeness, or usefulness of any data, apparatus, product, or process
 * disclosed, or represents that its use would not infringe privately owned
 * rights.
 *
 * Stanford disclaimer of liability
 * --------------------------------
 * Stanford University makes no representations or warranties, express or
 * implied, nor assumes any liability for the use of this software.
 *
 * Stanford disclaimer of copyright
 * --------------------------------
 * Stanford University, owner of the copyright, hereby disclaims its
 * copyright and all other rights in this software.  Hence, anyone may
 * freely use it for any purpose without restriction.
 *
 * Maintenance of notices
 * ----------------------
 * In the interest of clarity regarding the origin and status of this
 * SLAC software, this and all the preceding Stanford University notices
 * are to remain affixed to any copy or derivative of this software made
 * or distributed by the recipient and are to be affixed to any copy of
 * software made or distributed by the recipient that contains a copy or
 * derivative of this software.
 *
 * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
 */

#include <stdint.h>

#define NumberOf(arr)		(sizeof(arr)/sizeof(arr[0]))

#define FLASH_STRIDE(b)     4 /* bytes; currently fixed */
#define FLASH_WIDTH(b)      ((b)->width)
#define FLASH_NDEVS(b)      (FLASH_STRIDE(b)/FLASH_WIDTH(b))

/* Type declarations */

/* Registers          */
typedef uint8_t           _u8_a_t  __attribute__((may_alias));
typedef uint16_t          _u16_a_t __attribute__((may_alias));
typedef uint32_t          _u32_a_t __attribute__((may_alias));

/* Register addresses */
typedef volatile _u8_a_t  *A8;
typedef volatile _u16_a_t *A16;
typedef volatile _u32_a_t *A32;

struct flash_bank_ops;

/*
 * Description of a flash bank. Multiple
 * devices that are used in parallel to
 * make up words of FLASH_STRIDE bytes
 * are a 'physical' bank.
 *
 * A bank can even be a 'logical' bank
 * if it includes chip-select logic, i.e.,
 * int can contain multiple adjacent
 * 'physical' banks
 *
 * The BSP must provide an array of 'bankdesc'
 * structs and it must initialize the fields
 *
 *   'start'
 *     size of bank; may be set to zero to instruct
 *     the driver to scan a bank of 'max_size' for
 *     devices (i.e., bank may not be fully populated)
 *   'max_size'
 *     size of fully populated bank (defines address range
 *     that is scanned for devices).
 *     If 'max_size' is negative then scanning starts from
 *     the top rather than from the bottom.
 *   'width'
 *     width of a single device (in bytes). E.g., if
 *     2 16-bit devices are used to form a (ATM fixed)
 *     stride of 4 then 'width = 2'. If four 8-bit
 *     devices are employed then 'width=1'.
 *   'knownVendors'
 *     array of vendors descriptions to use for scanning
 *     the bank.
 *
 */
struct bankdesc {
	uint32_t	start;		/* start of bank (CPU address)              */
	uint32_t	size;		/* in bytes (figured out automatically)     */
	int			max_size;	/* in case multiple banks are adjacent;
	                         * if max_size < 0 then the bank is scanned
							 * backwards (from top->bottom) for devices
							 */
	int         width;      /* FIXME there might be implicit assumptions still
	                         * that width == 2
							 */
	struct vendesc        *knownVendors;
	/* TODO: we assume identical devices within a bank... */

	/* The next three variables cache information obtained
	 * from the applicable vendor and device descriptions.
	 * They are written by BSP_flashCheckId().
	 */
	uint32_t	fblksz;     /* block size in bytes; includes counting
	                         * parallel 16-bit devices, i.e., if a
							 * single device has a block-size of xxx
							 * then fblksz = xxx*ndevs.
							 */
	struct devdesc        *dd;
	struct flash_bank_ops *ops;
};

struct devdesc {
	uint32_t	id;     /* numerical ID (matched against
	                     * ID read from device).
						 */
	char		*name;  /* informational name           */
	uint32_t	size;	/* bytes                        */
	uint32_t	bufsz;	/* size of write buffer (bytes) */
	uint32_t	fblksz; /* sector/block size (bytes)    */
};

struct vendesc {
	uint32_t	id;     /* numerical ID (matched against
	                     * ID read from device).
						 */
	char		*name;  /* informational name */

	                    /* array of supported devices;
						 * the 'ops' specified below
						 * are used to access these devices
						 */
	struct devdesc	      *known_devs;
						/* access methods for talking to
						 * devices associated with this
						 * vendor description.
						 */
	struct flash_bank_ops *ops;
};

/* Device Access Methods ('ops'); these must be
 * implemented by low-level chip drivers
 */

struct flash_bank_ops {
/* Read vendor/device ID; Return 0 on success, nonzero if unable to read id */
	int            (*get_id)(struct bankdesc *b, uint32_t addr, uint32_t *pVendorId, uint32_t *pDeviceId);
/* Unlock block holding 'addr'ess
 *
 *   NOTES: - device switched back to array mode on exit.
 *          - 'addr' must be 32-bit aligned.
 */

	void           (*unlock_block)(struct bankdesc *b, uint32_t addr);
/* Lock block holding 'addr'ess
 *
 *   NOTES: - device switched back to array mode on exit.
 *          - 'addr' must be 32-bit aligned.
 */

	void           (*lock_block)(struct bankdesc *b, uint32_t addr);
/* Erase single block holding 'addr'ess. The routine may
 * assume that the address is block/sector aligned.
 *
 * RETURNS: zero on error, device status on failure.
 *
 *   NOTES: - device switched back to array mode on exit.
 *          - 'addr' must be 32-bit aligned.
 */
	int            (*erase_block)(struct bankdesc *b, uint32_t addr);
/* Query the status of the device and assert it's readiness
 * leave off in array-reading mode.
 *
 * RETURNS: 0 on success, error status (result of status query) on error.
 *
 *   NOTES: - error message is printed to stderr.
 *          - device switched back to array mode on exit.
 *          - 'addr' must be 32-bit aligned.
 */
	uint32_t       (*check_ready)(struct bankdesc *b, uint32_t addr);
/* Dump status bits (F_CMD_RD_STA results);
 * 'verbose' prints non-error bits, too
 */
	void           (*print_stat)(struct bankdesc *b, uint32_t sta, int verbose);
/* Switch to array mode; 'addr' can be assumed to be stride-aligned */
	void           (*array_mode)(struct bankdesc *b, uint32_t addr);
/* Write N bytes from 'src' to flash:
 * 'src[0] .. src[N-1]' -> addr[0]..addr[N-1].
 * N may be assumed to be a multiple of 'stride'
 * RETURNS: failure status or zero on success.
 */
	uint32_t       (*write_line)(struct bankdesc *b, uint32_t addr, char *src, uint32_t N);
};

/* BSP ops (detect banks, handle write-protection on board);
 * these must be implemented by the BSP.
 */

struct flash_bsp_ops {
/* Return descriptor for bank # 'bank' or NULL (invalid arg) */
	struct bankdesc *(*bankcheck)(int bank, int quiet);
/* set (enbl:1), clear (enbl:0) or query (enbl:-1)
 * on-board write protection.
 *
 * RETURNS 0 on success, nonzero on error.
 */
	int              (*flash_wp)(int bank, int enbl);
/* read a running us clock (for polling timeout) */
	uint32_t         (*read_us_timer)();
};

/* This must be provided by the BSP */
extern struct flash_bsp_ops BSP_flashBspOps;

/* Available low-level flash drivers, so far */
extern struct vendesc        BSP_flash_vendor_intel[];
extern struct vendesc        BSP_flash_vendor_spansion[];

#endif