b88abbb4704f105d3476a2301f64b20404406ef4
[openocd.git] / src / flash / nor / psoc5lp.c
1 /*
2 * PSoC 5LP flash driver
3 *
4 * Copyright (c) 2016 Andreas Färber
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 "imp.h"
25 #include <helper/time_support.h>
26 #include <target/armv7m.h>
27
28 #define PM_ACT_CFG0 0x400043A0
29 #define PM_ACT_CFG12 0x400043AC
30 #define SPC_CPU_DATA 0x40004720
31 #define SPC_SR 0x40004722
32 #define PRT1_PC2 0x4000500A
33 #define PHUB_CH0_BASIC_CFG 0x40007010
34 #define PHUB_CH0_ACTION 0x40007014
35 #define PHUB_CH0_BASIC_STATUS 0x40007018
36 #define PHUB_CH1_BASIC_CFG 0x40007020
37 #define PHUB_CH1_ACTION 0x40007024
38 #define PHUB_CH1_BASIC_STATUS 0x40007028
39 #define PHUB_CFGMEM0_CFG0 0x40007600
40 #define PHUB_CFGMEM0_CFG1 0x40007604
41 #define PHUB_CFGMEM1_CFG0 0x40007608
42 #define PHUB_CFGMEM1_CFG1 0x4000760C
43 #define PHUB_TDMEM0_ORIG_TD0 0x40007800
44 #define PHUB_TDMEM0_ORIG_TD1 0x40007804
45 #define PHUB_TDMEM1_ORIG_TD0 0x40007808
46 #define PHUB_TDMEM1_ORIG_TD1 0x4000780C
47 #define PANTHER_DEVICE_ID 0x4008001C
48
49 /* NVL is not actually mapped to the Cortex-M address space
50 * As we need a base addess different from other banks in the device
51 * we use the address of NVL programming data in Cypress images */
52 #define NVL_META_BASE 0x90000000
53
54 #define PM_ACT_CFG12_EN_EE (1 << 4)
55
56 #define SPC_KEY1 0xB6
57 #define SPC_KEY2 0xD3
58
59 #define SPC_LOAD_BYTE 0x00
60 #define SPC_LOAD_MULTI_BYTE 0x01
61 #define SPC_LOAD_ROW 0x02
62 #define SPC_READ_BYTE 0x03
63 #define SPC_READ_MULTI_BYTE 0x04
64 #define SPC_WRITE_ROW 0x05
65 #define SPC_WRITE_USER_NVL 0x06
66 #define SPC_PRG_ROW 0x07
67 #define SPC_ERASE_SECTOR 0x08
68 #define SPC_ERASE_ALL 0x09
69 #define SPC_READ_HIDDEN_ROW 0x0A
70 #define SPC_PROGRAM_PROTECT_ROW 0x0B
71 #define SPC_GET_CHECKSUM 0x0C
72 #define SPC_GET_TEMP 0x0E
73 #define SPC_READ_VOLATILE_BYTE 0x10
74
75 #define SPC_ARRAY_ALL 0x3F
76 #define SPC_ARRAY_EEPROM 0x40
77 #define SPC_ARRAY_NVL_USER 0x80
78 #define SPC_ARRAY_NVL_WO 0xF8
79
80 #define SPC_ROW_PROTECTION 0
81
82 #define SPC_OPCODE_LEN 3
83
84 #define SPC_SR_DATA_READY (1 << 0)
85 #define SPC_SR_IDLE (1 << 1)
86
87 #define PM_ACT_CFG0_EN_CLK_SPC (1 << 3)
88
89 #define PHUB_CHx_BASIC_CFG_EN (1 << 0)
90 #define PHUB_CHx_BASIC_CFG_WORK_SEP (1 << 5)
91
92 #define PHUB_CHx_ACTION_CPU_REQ (1 << 0)
93
94 #define PHUB_CFGMEMx_CFG0 (1 << 7)
95
96 #define PHUB_TDMEMx_ORIG_TD0_NEXT_TD_PTR_LAST (0xff << 16)
97 #define PHUB_TDMEMx_ORIG_TD0_INC_SRC_ADDR (1 << 24)
98
99 #define NVL_3_ECCEN (1 << 3)
100
101 #define ROW_SIZE 256
102 #define ROW_ECC_SIZE 32
103 #define ROWS_PER_SECTOR 64
104 #define SECTOR_SIZE (ROWS_PER_SECTOR * ROW_SIZE)
105 #define ROWS_PER_BLOCK 256
106 #define BLOCK_SIZE (ROWS_PER_BLOCK * ROW_SIZE)
107 #define SECTORS_PER_BLOCK (BLOCK_SIZE / SECTOR_SIZE)
108 #define EEPROM_ROW_SIZE 16
109 #define EEPROM_SECTOR_SIZE (ROWS_PER_SECTOR * EEPROM_ROW_SIZE)
110 #define EEPROM_BLOCK_SIZE (ROWS_PER_BLOCK * EEPROM_ROW_SIZE)
111
112 #define PART_NUMBER_LEN (17 + 1)
113
114 struct psoc5lp_device {
115 uint32_t id;
116 unsigned fam;
117 unsigned speed_mhz;
118 unsigned flash_kb;
119 unsigned eeprom_kb;
120 };
121
122 /*
123 * Device information collected from datasheets.
124 * Different temperature ranges (C/I/Q/A) may share IDs, not differing otherwise.
125 */
126 static const struct psoc5lp_device psoc5lp_devices[] = {
127 /* CY8C58LP Family Datasheet */
128 { .id = 0x2E11F069, .fam = 8, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },
129 { .id = 0x2E120069, .fam = 8, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },
130 { .id = 0x2E123069, .fam = 8, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },
131 { .id = 0x2E124069, .fam = 8, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },
132 { .id = 0x2E126069, .fam = 8, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },
133 { .id = 0x2E127069, .fam = 8, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },
134 { .id = 0x2E117069, .fam = 8, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },
135 { .id = 0x2E118069, .fam = 8, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },
136 { .id = 0x2E119069, .fam = 8, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },
137 { .id = 0x2E11C069, .fam = 8, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },
138 { .id = 0x2E114069, .fam = 8, .speed_mhz = 67, .flash_kb = 64, .eeprom_kb = 2 },
139 { .id = 0x2E115069, .fam = 8, .speed_mhz = 67, .flash_kb = 64, .eeprom_kb = 2 },
140 { .id = 0x2E116069, .fam = 8, .speed_mhz = 67, .flash_kb = 64, .eeprom_kb = 2 },
141 { .id = 0x2E160069, .fam = 8, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },
142 /* '' */
143 { .id = 0x2E161069, .fam = 8, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },
144 /* '' */
145 { .id = 0x2E1D2069, .fam = 8, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },
146 { .id = 0x2E1D6069, .fam = 8, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },
147
148 /* CY8C56LP Family Datasheet */
149 { .id = 0x2E10A069, .fam = 6, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },
150 { .id = 0x2E10D069, .fam = 6, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },
151 { .id = 0x2E10E069, .fam = 6, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },
152 { .id = 0x2E106069, .fam = 6, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },
153 { .id = 0x2E108069, .fam = 6, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },
154 { .id = 0x2E109069, .fam = 6, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },
155 { .id = 0x2E101069, .fam = 6, .speed_mhz = 67, .flash_kb = 64, .eeprom_kb = 2 },
156 { .id = 0x2E104069, .fam = 6, .speed_mhz = 67, .flash_kb = 64, .eeprom_kb = 2 },
157 /* '' */
158 { .id = 0x2E105069, .fam = 6, .speed_mhz = 67, .flash_kb = 64, .eeprom_kb = 2 },
159 { .id = 0x2E128069, .fam = 6, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },
160 /* '' */
161 { .id = 0x2E122069, .fam = 6, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },
162 { .id = 0x2E129069, .fam = 6, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },
163 { .id = 0x2E163069, .fam = 6, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },
164 { .id = 0x2E156069, .fam = 6, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },
165 { .id = 0x2E1D3069, .fam = 6, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },
166
167 /* CY8C54LP Family Datasheet */
168 { .id = 0x2E11A069, .fam = 4, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },
169 { .id = 0x2E16A069, .fam = 4, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },
170 { .id = 0x2E12A069, .fam = 4, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },
171 { .id = 0x2E103069, .fam = 4, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },
172 { .id = 0x2E16C069, .fam = 4, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },
173 { .id = 0x2E102069, .fam = 4, .speed_mhz = 67, .flash_kb = 64, .eeprom_kb = 2 },
174 { .id = 0x2E148069, .fam = 4, .speed_mhz = 67, .flash_kb = 64, .eeprom_kb = 2 },
175 { .id = 0x2E155069, .fam = 4, .speed_mhz = 67, .flash_kb = 64, .eeprom_kb = 2 },
176 { .id = 0x2E16B069, .fam = 4, .speed_mhz = 67, .flash_kb = 64, .eeprom_kb = 2 },
177 { .id = 0x2E12B069, .fam = 4, .speed_mhz = 67, .flash_kb = 32, .eeprom_kb = 2 },
178 { .id = 0x2E168069, .fam = 4, .speed_mhz = 67, .flash_kb = 32, .eeprom_kb = 2 },
179 { .id = 0x2E178069, .fam = 4, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },
180 { .id = 0x2E15D069, .fam = 4, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },
181 { .id = 0x2E1D4069, .fam = 4, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },
182
183 /* CY8C52LP Family Datasheet */
184 { .id = 0x2E11E069, .fam = 2, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },
185 { .id = 0x2E12F069, .fam = 2, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },
186 { .id = 0x2E133069, .fam = 2, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },
187 { .id = 0x2E159069, .fam = 2, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },
188 { .id = 0x2E11D069, .fam = 2, .speed_mhz = 67, .flash_kb = 64, .eeprom_kb = 2 },
189 { .id = 0x2E121069, .fam = 2, .speed_mhz = 67, .flash_kb = 64, .eeprom_kb = 2 },
190 { .id = 0x2E184069, .fam = 2, .speed_mhz = 67, .flash_kb = 64, .eeprom_kb = 2 },
191 { .id = 0x2E196069, .fam = 2, .speed_mhz = 67, .flash_kb = 64, .eeprom_kb = 2 },
192 { .id = 0x2E132069, .fam = 2, .speed_mhz = 67, .flash_kb = 32, .eeprom_kb = 2 },
193 { .id = 0x2E138069, .fam = 2, .speed_mhz = 67, .flash_kb = 32, .eeprom_kb = 2 },
194 { .id = 0x2E13A069, .fam = 2, .speed_mhz = 67, .flash_kb = 32, .eeprom_kb = 2 },
195 { .id = 0x2E152069, .fam = 2, .speed_mhz = 67, .flash_kb = 32, .eeprom_kb = 2 },
196 { .id = 0x2E15F069, .fam = 2, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },
197 { .id = 0x2E15A069, .fam = 2, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },
198 { .id = 0x2E1D5069, .fam = 2, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },
199 };
200
201 static void psoc5lp_get_part_number(const struct psoc5lp_device *dev, char *str)
202 {
203 strcpy(str, "CY8Cabcdefg-LPxxx");
204
205 str[4] = '5';
206 str[5] = '0' + dev->fam;
207
208 switch (dev->speed_mhz) {
209 case 67:
210 str[6] = '6';
211 break;
212 case 80:
213 str[6] = '8';
214 break;
215 default:
216 str[6] = '?';
217 }
218
219 switch (dev->flash_kb) {
220 case 32:
221 str[7] = '5';
222 break;
223 case 64:
224 str[7] = '6';
225 break;
226 case 128:
227 str[7] = '7';
228 break;
229 case 256:
230 str[7] = '8';
231 break;
232 default:
233 str[7] = '?';
234 }
235
236 /* Package does not matter. */
237 str[8] = 'x';
238 str[9] = 'x';
239
240 /* Temperate range cannot uniquely be identified. */
241 str[10] = 'x';
242 }
243
244 static int psoc5lp_get_device_id(struct target *target, uint32_t *id)
245 {
246 int retval;
247
248 retval = target_read_u32(target, PANTHER_DEVICE_ID, id); /* dummy read */
249 if (retval != ERROR_OK)
250 return retval;
251 retval = target_read_u32(target, PANTHER_DEVICE_ID, id);
252 return retval;
253 }
254
255 static int psoc5lp_find_device(struct target *target,
256 const struct psoc5lp_device **device)
257 {
258 uint32_t device_id;
259 unsigned i;
260 int retval;
261
262 *device = NULL;
263
264 retval = psoc5lp_get_device_id(target, &device_id);
265 if (retval != ERROR_OK)
266 return retval;
267 LOG_DEBUG("PANTHER_DEVICE_ID = 0x%08" PRIX32, device_id);
268
269 for (i = 0; i < ARRAY_SIZE(psoc5lp_devices); i++) {
270 if (psoc5lp_devices[i].id == device_id) {
271 *device = &psoc5lp_devices[i];
272 return ERROR_OK;
273 }
274 }
275
276 LOG_ERROR("Device 0x%08" PRIX32 " not supported", device_id);
277 return ERROR_FLASH_OPER_UNSUPPORTED;
278 }
279
280 static int psoc5lp_spc_enable_clock(struct target *target)
281 {
282 int retval;
283 uint8_t pm_act_cfg0;
284
285 retval = target_read_u8(target, PM_ACT_CFG0, &pm_act_cfg0);
286 if (retval != ERROR_OK) {
287 LOG_ERROR("Cannot read PM_ACT_CFG0");
288 return retval;
289 }
290
291 if (pm_act_cfg0 & PM_ACT_CFG0_EN_CLK_SPC)
292 return ERROR_OK; /* clock already enabled */
293
294 retval = target_write_u8(target, PM_ACT_CFG0, pm_act_cfg0 | PM_ACT_CFG0_EN_CLK_SPC);
295 if (retval != ERROR_OK)
296 LOG_ERROR("Cannot enable SPC clock");
297
298 return retval;
299 }
300
301 static int psoc5lp_spc_write_opcode(struct target *target, uint8_t opcode)
302 {
303 int retval;
304
305 retval = target_write_u8(target, SPC_CPU_DATA, SPC_KEY1);
306 if (retval != ERROR_OK)
307 return retval;
308 retval = target_write_u8(target, SPC_CPU_DATA, SPC_KEY2 + opcode);
309 if (retval != ERROR_OK)
310 return retval;
311 retval = target_write_u8(target, SPC_CPU_DATA, opcode);
312 return retval;
313 }
314
315 static void psoc5lp_spc_write_opcode_buffer(struct target *target,
316 uint8_t *buf, uint8_t opcode)
317 {
318 buf[0] = SPC_KEY1;
319 buf[1] = SPC_KEY2 + opcode;
320 buf[2] = opcode;
321 }
322
323 static int psoc5lp_spc_busy_wait_data(struct target *target)
324 {
325 int64_t endtime;
326 uint8_t sr;
327 int retval;
328
329 retval = target_read_u8(target, SPC_SR, &sr); /* dummy read */
330 if (retval != ERROR_OK)
331 return retval;
332
333 endtime = timeval_ms() + 1000; /* 1 second timeout */
334 do {
335 alive_sleep(1);
336 retval = target_read_u8(target, SPC_SR, &sr);
337 if (retval != ERROR_OK)
338 return retval;
339 if (sr == SPC_SR_DATA_READY)
340 return ERROR_OK;
341 } while (timeval_ms() < endtime);
342
343 return ERROR_FLASH_OPERATION_FAILED;
344 }
345
346 static int psoc5lp_spc_busy_wait_idle(struct target *target)
347 {
348 int64_t endtime;
349 uint8_t sr;
350 int retval;
351
352 retval = target_read_u8(target, SPC_SR, &sr); /* dummy read */
353 if (retval != ERROR_OK)
354 return retval;
355
356 endtime = timeval_ms() + 1000; /* 1 second timeout */
357 do {
358 alive_sleep(1);
359 retval = target_read_u8(target, SPC_SR, &sr);
360 if (retval != ERROR_OK)
361 return retval;
362 if (sr == SPC_SR_IDLE)
363 return ERROR_OK;
364 } while (timeval_ms() < endtime);
365
366 return ERROR_FLASH_OPERATION_FAILED;
367 }
368
369 static int psoc5lp_spc_load_byte(struct target *target,
370 uint8_t array_id, uint8_t offset, uint8_t value)
371 {
372 int retval;
373
374 retval = psoc5lp_spc_write_opcode(target, SPC_LOAD_BYTE);
375 if (retval != ERROR_OK)
376 return retval;
377 retval = target_write_u8(target, SPC_CPU_DATA, array_id);
378 if (retval != ERROR_OK)
379 return retval;
380 retval = target_write_u8(target, SPC_CPU_DATA, offset);
381 if (retval != ERROR_OK)
382 return retval;
383 retval = target_write_u8(target, SPC_CPU_DATA, value);
384 if (retval != ERROR_OK)
385 return retval;
386
387 retval = psoc5lp_spc_busy_wait_idle(target);
388 if (retval != ERROR_OK)
389 return retval;
390
391 return ERROR_OK;
392 }
393
394 static int psoc5lp_spc_load_row(struct target *target,
395 uint8_t array_id, const uint8_t *data, unsigned row_size)
396 {
397 unsigned i;
398 int retval;
399
400 retval = psoc5lp_spc_write_opcode(target, SPC_LOAD_ROW);
401 if (retval != ERROR_OK)
402 return retval;
403 retval = target_write_u8(target, SPC_CPU_DATA, array_id);
404 if (retval != ERROR_OK)
405 return retval;
406
407 for (i = 0; i < row_size; i++) {
408 retval = target_write_u8(target, SPC_CPU_DATA, data[i]);
409 if (retval != ERROR_OK)
410 return retval;
411 }
412
413 retval = psoc5lp_spc_busy_wait_idle(target);
414 if (retval != ERROR_OK)
415 return retval;
416
417 return ERROR_OK;
418 }
419
420 static int psoc5lp_spc_read_byte(struct target *target,
421 uint8_t array_id, uint8_t offset, uint8_t *data)
422 {
423 int retval;
424
425 retval = psoc5lp_spc_write_opcode(target, SPC_READ_BYTE);
426 if (retval != ERROR_OK)
427 return retval;
428 retval = target_write_u8(target, SPC_CPU_DATA, array_id);
429 if (retval != ERROR_OK)
430 return retval;
431 retval = target_write_u8(target, SPC_CPU_DATA, offset);
432 if (retval != ERROR_OK)
433 return retval;
434
435 retval = psoc5lp_spc_busy_wait_data(target);
436 if (retval != ERROR_OK)
437 return retval;
438
439 retval = target_read_u8(target, SPC_CPU_DATA, data);
440 if (retval != ERROR_OK)
441 return retval;
442
443 retval = psoc5lp_spc_busy_wait_idle(target);
444 if (retval != ERROR_OK)
445 return retval;
446
447 return ERROR_OK;
448 }
449
450 static int psoc5lp_spc_write_row(struct target *target,
451 uint8_t array_id, uint16_t row_id, const uint8_t *temp)
452 {
453 int retval;
454
455 retval = psoc5lp_spc_write_opcode(target, SPC_WRITE_ROW);
456 if (retval != ERROR_OK)
457 return retval;
458 retval = target_write_u8(target, SPC_CPU_DATA, array_id);
459 if (retval != ERROR_OK)
460 return retval;
461 retval = target_write_u8(target, SPC_CPU_DATA, row_id >> 8);
462 if (retval != ERROR_OK)
463 return retval;
464 retval = target_write_u8(target, SPC_CPU_DATA, row_id & 0xff);
465 if (retval != ERROR_OK)
466 return retval;
467 retval = target_write_u8(target, SPC_CPU_DATA, temp[0]);
468 if (retval != ERROR_OK)
469 return retval;
470 retval = target_write_u8(target, SPC_CPU_DATA, temp[1]);
471 if (retval != ERROR_OK)
472 return retval;
473
474 retval = psoc5lp_spc_busy_wait_idle(target);
475 if (retval != ERROR_OK)
476 return retval;
477
478 return ERROR_OK;
479 }
480
481 static int psoc5lp_spc_write_user_nvl(struct target *target,
482 uint8_t array_id)
483 {
484 int retval;
485
486 retval = psoc5lp_spc_write_opcode(target, SPC_WRITE_USER_NVL);
487 if (retval != ERROR_OK)
488 return retval;
489 retval = target_write_u8(target, SPC_CPU_DATA, array_id);
490 if (retval != ERROR_OK)
491 return retval;
492
493 retval = psoc5lp_spc_busy_wait_idle(target);
494 if (retval != ERROR_OK)
495 return retval;
496
497 return ERROR_OK;
498 }
499
500 static int psoc5lp_spc_erase_sector(struct target *target,
501 uint8_t array_id, uint8_t row_id)
502 {
503 int retval;
504
505 retval = psoc5lp_spc_write_opcode(target, SPC_ERASE_SECTOR);
506 if (retval != ERROR_OK)
507 return retval;
508 retval = target_write_u8(target, SPC_CPU_DATA, array_id);
509 if (retval != ERROR_OK)
510 return retval;
511 retval = target_write_u8(target, SPC_CPU_DATA, row_id);
512 if (retval != ERROR_OK)
513 return retval;
514
515 retval = psoc5lp_spc_busy_wait_idle(target);
516 if (retval != ERROR_OK)
517 return retval;
518
519 return ERROR_OK;
520 }
521
522 static int psoc5lp_spc_erase_all(struct target *target)
523 {
524 int retval;
525
526 retval = psoc5lp_spc_write_opcode(target, SPC_ERASE_ALL);
527 if (retval != ERROR_OK)
528 return retval;
529
530 retval = psoc5lp_spc_busy_wait_idle(target);
531 if (retval != ERROR_OK)
532 return retval;
533
534 return ERROR_OK;
535 }
536
537 static int psoc5lp_spc_read_hidden_row(struct target *target,
538 uint8_t array_id, uint8_t row_id, uint8_t *data)
539 {
540 int i, retval;
541
542 retval = psoc5lp_spc_write_opcode(target, SPC_READ_HIDDEN_ROW);
543 if (retval != ERROR_OK)
544 return retval;
545 retval = target_write_u8(target, SPC_CPU_DATA, array_id);
546 if (retval != ERROR_OK)
547 return retval;
548 retval = target_write_u8(target, SPC_CPU_DATA, row_id);
549 if (retval != ERROR_OK)
550 return retval;
551
552 retval = psoc5lp_spc_busy_wait_data(target);
553 if (retval != ERROR_OK)
554 return retval;
555
556 for (i = 0; i < ROW_SIZE; i++) {
557 retval = target_read_u8(target, SPC_CPU_DATA, &data[i]);
558 if (retval != ERROR_OK)
559 return retval;
560 }
561
562 retval = psoc5lp_spc_busy_wait_idle(target);
563 if (retval != ERROR_OK)
564 return retval;
565
566 return ERROR_OK;
567 }
568
569 static int psoc5lp_spc_get_temp(struct target *target, uint8_t samples,
570 uint8_t *data)
571 {
572 int retval;
573
574 retval = psoc5lp_spc_write_opcode(target, SPC_GET_TEMP);
575 if (retval != ERROR_OK)
576 return retval;
577 retval = target_write_u8(target, SPC_CPU_DATA, samples);
578 if (retval != ERROR_OK)
579 return retval;
580
581 retval = psoc5lp_spc_busy_wait_data(target);
582 if (retval != ERROR_OK)
583 return retval;
584
585 retval = target_read_u8(target, SPC_CPU_DATA, &data[0]);
586 if (retval != ERROR_OK)
587 return retval;
588 retval = target_read_u8(target, SPC_CPU_DATA, &data[1]);
589 if (retval != ERROR_OK)
590 return retval;
591
592 retval = psoc5lp_spc_busy_wait_idle(target);
593 if (retval != ERROR_OK)
594 return retval;
595
596 return ERROR_OK;
597 }
598
599 static int psoc5lp_spc_read_volatile_byte(struct target *target,
600 uint8_t array_id, uint8_t offset, uint8_t *data)
601 {
602 int retval;
603
604 retval = psoc5lp_spc_write_opcode(target, SPC_READ_VOLATILE_BYTE);
605 if (retval != ERROR_OK)
606 return retval;
607 retval = target_write_u8(target, SPC_CPU_DATA, array_id);
608 if (retval != ERROR_OK)
609 return retval;
610 retval = target_write_u8(target, SPC_CPU_DATA, offset);
611 if (retval != ERROR_OK)
612 return retval;
613
614 retval = psoc5lp_spc_busy_wait_data(target);
615 if (retval != ERROR_OK)
616 return retval;
617
618 retval = target_read_u8(target, SPC_CPU_DATA, data);
619 if (retval != ERROR_OK)
620 return retval;
621
622 retval = psoc5lp_spc_busy_wait_idle(target);
623 if (retval != ERROR_OK)
624 return retval;
625
626 return ERROR_OK;
627 }
628
629 /*
630 * NV Latch
631 */
632
633 struct psoc5lp_nvl_flash_bank {
634 bool probed;
635 const struct psoc5lp_device *device;
636 };
637
638 static int psoc5lp_nvl_read(struct flash_bank *bank,
639 uint8_t *buffer, uint32_t offset, uint32_t count)
640 {
641 int retval;
642
643 retval = psoc5lp_spc_enable_clock(bank->target);
644 if (retval != ERROR_OK)
645 return retval;
646
647 while (count > 0) {
648 retval = psoc5lp_spc_read_byte(bank->target,
649 SPC_ARRAY_NVL_USER, offset, buffer);
650 if (retval != ERROR_OK)
651 return retval;
652 buffer++;
653 offset++;
654 count--;
655 }
656
657 return ERROR_OK;
658 }
659
660 static int psoc5lp_nvl_erase(struct flash_bank *bank, int first, int last)
661 {
662 LOG_WARNING("There is no erase operation for NV Latches");
663 return ERROR_FLASH_OPER_UNSUPPORTED;
664 }
665
666 static int psoc5lp_nvl_erase_check(struct flash_bank *bank)
667 {
668 int i;
669
670 for (i = 0; i < bank->num_sectors; i++)
671 bank->sectors[i].is_erased = 0;
672
673 return ERROR_OK;
674 }
675
676 static int psoc5lp_nvl_write(struct flash_bank *bank,
677 const uint8_t *buffer, uint32_t offset, uint32_t byte_count)
678 {
679 struct target *target = bank->target;
680 uint8_t *current_data, val;
681 bool write_required = false, pullup_needed = false, ecc_changed = false;
682 uint32_t i;
683 int retval;
684
685 if (offset != 0 || byte_count != bank->size) {
686 LOG_ERROR("NVL can only be written in whole");
687 return ERROR_FLASH_OPER_UNSUPPORTED;
688 }
689
690 current_data = calloc(1, bank->size);
691 if (!current_data)
692 return ERROR_FAIL;
693 retval = psoc5lp_nvl_read(bank, current_data, offset, byte_count);
694 if (retval != ERROR_OK) {
695 free(current_data);
696 return retval;
697 }
698 for (i = offset; i < byte_count; i++) {
699 if (current_data[i] != buffer[i]) {
700 write_required = true;
701 break;
702 }
703 }
704 if (((buffer[2] & 0x80) == 0x80) && ((current_data[0] & 0x0C) != 0x08))
705 pullup_needed = true;
706 if (((buffer[3] ^ current_data[3]) & 0x08) == 0x08)
707 ecc_changed = true;
708 free(current_data);
709
710 if (!write_required) {
711 LOG_INFO("Unchanged, skipping NVL write");
712 return ERROR_OK;
713 }
714 if (pullup_needed) {
715 retval = target_read_u8(target, PRT1_PC2, &val);
716 if (retval != ERROR_OK)
717 return retval;
718 val &= 0xF0;
719 val |= 0x05;
720 retval = target_write_u8(target, PRT1_PC2, val);
721 if (retval != ERROR_OK)
722 return retval;
723 }
724
725 for (i = offset; i < byte_count; i++) {
726 retval = psoc5lp_spc_load_byte(target,
727 SPC_ARRAY_NVL_USER, i, buffer[i]);
728 if (retval != ERROR_OK)
729 return retval;
730
731 retval = psoc5lp_spc_read_volatile_byte(target,
732 SPC_ARRAY_NVL_USER, i, &val);
733 if (retval != ERROR_OK)
734 return retval;
735 if (val != buffer[i]) {
736 LOG_ERROR("Failed to load NVL byte %" PRIu32 ": "
737 "expected 0x%02" PRIx8 ", read 0x%02" PRIx8,
738 i, buffer[i], val);
739 return ERROR_FLASH_OPERATION_FAILED;
740 }
741 }
742
743 retval = psoc5lp_spc_write_user_nvl(target, SPC_ARRAY_NVL_USER);
744 if (retval != ERROR_OK)
745 return retval;
746
747 if (ecc_changed) {
748 retval = target_call_reset_callbacks(target, RESET_INIT);
749 if (retval != ERROR_OK)
750 LOG_WARNING("Reset failed after enabling or disabling ECC");
751 }
752
753 return ERROR_OK;
754 }
755
756 static int psoc5lp_nvl_protect_check(struct flash_bank *bank)
757 {
758 int i;
759
760 for (i = 0; i < bank->num_sectors; i++)
761 bank->sectors[i].is_protected = -1;
762
763 return ERROR_OK;
764 }
765
766 static int psoc5lp_nvl_get_info_command(struct flash_bank *bank,
767 char *buf, int buf_size)
768 {
769 struct psoc5lp_nvl_flash_bank *psoc_nvl_bank = bank->driver_priv;
770 char part_number[PART_NUMBER_LEN];
771
772 psoc5lp_get_part_number(psoc_nvl_bank->device, part_number);
773
774 snprintf(buf, buf_size, "%s", part_number);
775
776 return ERROR_OK;
777 }
778
779 static int psoc5lp_nvl_probe(struct flash_bank *bank)
780 {
781 struct psoc5lp_nvl_flash_bank *psoc_nvl_bank = bank->driver_priv;
782 int retval;
783
784 if (psoc_nvl_bank->probed)
785 return ERROR_OK;
786
787 if (bank->target->state != TARGET_HALTED) {
788 LOG_ERROR("Target not halted");
789 return ERROR_TARGET_NOT_HALTED;
790 }
791
792 retval = psoc5lp_find_device(bank->target, &psoc_nvl_bank->device);
793 if (retval != ERROR_OK)
794 return retval;
795
796 bank->base = NVL_META_BASE;
797 bank->size = 4;
798 bank->num_sectors = 1;
799 bank->sectors = calloc(bank->num_sectors,
800 sizeof(struct flash_sector));
801 bank->sectors[0].offset = 0;
802 bank->sectors[0].size = 4;
803 bank->sectors[0].is_erased = -1;
804 bank->sectors[0].is_protected = -1;
805
806 psoc_nvl_bank->probed = true;
807
808 return ERROR_OK;
809 }
810
811 static int psoc5lp_nvl_auto_probe(struct flash_bank *bank)
812 {
813 struct psoc5lp_nvl_flash_bank *psoc_nvl_bank = bank->driver_priv;
814
815 if (psoc_nvl_bank->probed)
816 return ERROR_OK;
817
818 return psoc5lp_nvl_probe(bank);
819 }
820
821 FLASH_BANK_COMMAND_HANDLER(psoc5lp_nvl_flash_bank_command)
822 {
823 struct psoc5lp_nvl_flash_bank *psoc_nvl_bank;
824
825 psoc_nvl_bank = malloc(sizeof(struct psoc5lp_nvl_flash_bank));
826 if (!psoc_nvl_bank)
827 return ERROR_FLASH_OPERATION_FAILED;
828
829 psoc_nvl_bank->probed = false;
830
831 bank->driver_priv = psoc_nvl_bank;
832
833 return ERROR_OK;
834 }
835
836 static const struct command_registration psoc5lp_nvl_exec_command_handlers[] = {
837 COMMAND_REGISTRATION_DONE
838 };
839
840 static const struct command_registration psoc5lp_nvl_command_handlers[] = {
841 {
842 .name = "psoc5lp_nvl",
843 .mode = COMMAND_ANY,
844 .help = "PSoC 5LP NV Latch command group",
845 .usage = "",
846 .chain = psoc5lp_nvl_exec_command_handlers,
847 },
848 COMMAND_REGISTRATION_DONE
849 };
850
851 struct flash_driver psoc5lp_nvl_flash = {
852 .name = "psoc5lp_nvl",
853 .commands = psoc5lp_nvl_command_handlers,
854 .flash_bank_command = psoc5lp_nvl_flash_bank_command,
855 .info = psoc5lp_nvl_get_info_command,
856 .probe = psoc5lp_nvl_probe,
857 .auto_probe = psoc5lp_nvl_auto_probe,
858 .protect_check = psoc5lp_nvl_protect_check,
859 .read = psoc5lp_nvl_read,
860 .erase = psoc5lp_nvl_erase,
861 .erase_check = psoc5lp_nvl_erase_check,
862 .write = psoc5lp_nvl_write,
863 .free_driver_priv = default_flash_free_driver_priv,
864 };
865
866 /*
867 * EEPROM
868 */
869
870 struct psoc5lp_eeprom_flash_bank {
871 bool probed;
872 const struct psoc5lp_device *device;
873 };
874
875 static int psoc5lp_eeprom_erase(struct flash_bank *bank, int first, int last)
876 {
877 int i, retval;
878
879 for (i = first; i <= last; i++) {
880 retval = psoc5lp_spc_erase_sector(bank->target,
881 SPC_ARRAY_EEPROM, i);
882 if (retval != ERROR_OK)
883 return retval;
884 }
885
886 return ERROR_OK;
887 }
888
889 static int psoc5lp_eeprom_write(struct flash_bank *bank,
890 const uint8_t *buffer, uint32_t offset, uint32_t byte_count)
891 {
892 struct target *target = bank->target;
893 uint8_t temp[2];
894 unsigned row;
895 int retval;
896
897 if (offset % EEPROM_ROW_SIZE != 0) {
898 LOG_ERROR("Writes must be row-aligned, got offset 0x%08" PRIx32,
899 offset);
900 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
901 }
902
903 retval = psoc5lp_spc_get_temp(target, 3, temp);
904 if (retval != ERROR_OK) {
905 LOG_ERROR("Unable to read Die temperature");
906 return retval;
907 }
908 LOG_DEBUG("Get_Temp: sign 0x%02" PRIx8 ", magnitude 0x%02" PRIx8,
909 temp[0], temp[1]);
910
911 for (row = offset / EEPROM_ROW_SIZE; byte_count >= EEPROM_ROW_SIZE; row++) {
912 retval = psoc5lp_spc_load_row(target, SPC_ARRAY_EEPROM,
913 buffer, EEPROM_ROW_SIZE);
914 if (retval != ERROR_OK)
915 return retval;
916
917 retval = psoc5lp_spc_write_row(target, SPC_ARRAY_EEPROM,
918 row, temp);
919 if (retval != ERROR_OK)
920 return retval;
921
922 buffer += EEPROM_ROW_SIZE;
923 byte_count -= EEPROM_ROW_SIZE;
924 offset += EEPROM_ROW_SIZE;
925 }
926 if (byte_count > 0) {
927 uint8_t buf[EEPROM_ROW_SIZE];
928
929 memcpy(buf, buffer, byte_count);
930 memset(buf + byte_count, bank->default_padded_value,
931 EEPROM_ROW_SIZE - byte_count);
932
933 LOG_DEBUG("Padding %d bytes", EEPROM_ROW_SIZE - byte_count);
934 retval = psoc5lp_spc_load_row(target, SPC_ARRAY_EEPROM,
935 buf, EEPROM_ROW_SIZE);
936 if (retval != ERROR_OK)
937 return retval;
938
939 retval = psoc5lp_spc_write_row(target, SPC_ARRAY_EEPROM,
940 row, temp);
941 if (retval != ERROR_OK)
942 return retval;
943 }
944
945 return ERROR_OK;
946 }
947
948 static int psoc5lp_eeprom_protect_check(struct flash_bank *bank)
949 {
950 int i;
951
952 for (i = 0; i < bank->num_sectors; i++)
953 bank->sectors[i].is_protected = -1;
954
955 return ERROR_OK;
956 }
957
958 static int psoc5lp_eeprom_get_info_command(struct flash_bank *bank, char *buf, int buf_size)
959 {
960 struct psoc5lp_eeprom_flash_bank *psoc_eeprom_bank = bank->driver_priv;
961 char part_number[PART_NUMBER_LEN];
962
963 psoc5lp_get_part_number(psoc_eeprom_bank->device, part_number);
964
965 snprintf(buf, buf_size, "%s", part_number);
966
967 return ERROR_OK;
968 }
969
970 static int psoc5lp_eeprom_probe(struct flash_bank *bank)
971 {
972 struct psoc5lp_eeprom_flash_bank *psoc_eeprom_bank = bank->driver_priv;
973 uint32_t flash_addr = bank->base;
974 uint32_t val;
975 int i, retval;
976
977 if (psoc_eeprom_bank->probed)
978 return ERROR_OK;
979
980 if (bank->target->state != TARGET_HALTED) {
981 LOG_ERROR("Target not halted");
982 return ERROR_TARGET_NOT_HALTED;
983 }
984
985 retval = psoc5lp_find_device(bank->target, &psoc_eeprom_bank->device);
986 if (retval != ERROR_OK)
987 return retval;
988
989 retval = target_read_u32(bank->target, PM_ACT_CFG12, &val);
990 if (retval != ERROR_OK)
991 return retval;
992 if (!(val & PM_ACT_CFG12_EN_EE)) {
993 val |= PM_ACT_CFG12_EN_EE;
994 retval = target_write_u32(bank->target, PM_ACT_CFG12, val);
995 if (retval != ERROR_OK)
996 return retval;
997 }
998
999 bank->size = psoc_eeprom_bank->device->eeprom_kb * 1024;
1000 bank->num_sectors = DIV_ROUND_UP(bank->size, EEPROM_SECTOR_SIZE);
1001 bank->sectors = calloc(bank->num_sectors,
1002 sizeof(struct flash_sector));
1003 for (i = 0; i < bank->num_sectors; i++) {
1004 bank->sectors[i].size = EEPROM_SECTOR_SIZE;
1005 bank->sectors[i].offset = flash_addr - bank->base;
1006 bank->sectors[i].is_erased = -1;
1007 bank->sectors[i].is_protected = -1;
1008
1009 flash_addr += bank->sectors[i].size;
1010 }
1011
1012 bank->default_padded_value = bank->erased_value = 0x00;
1013
1014 psoc_eeprom_bank->probed = true;
1015
1016 return ERROR_OK;
1017 }
1018
1019 static int psoc5lp_eeprom_auto_probe(struct flash_bank *bank)
1020 {
1021 struct psoc5lp_eeprom_flash_bank *psoc_eeprom_bank = bank->driver_priv;
1022
1023 if (psoc_eeprom_bank->probed)
1024 return ERROR_OK;
1025
1026 return psoc5lp_eeprom_probe(bank);
1027 }
1028
1029 FLASH_BANK_COMMAND_HANDLER(psoc5lp_eeprom_flash_bank_command)
1030 {
1031 struct psoc5lp_eeprom_flash_bank *psoc_eeprom_bank;
1032
1033 psoc_eeprom_bank = malloc(sizeof(struct psoc5lp_eeprom_flash_bank));
1034 if (!psoc_eeprom_bank)
1035 return ERROR_FLASH_OPERATION_FAILED;
1036
1037 psoc_eeprom_bank->probed = false;
1038 psoc_eeprom_bank->device = NULL;
1039
1040 bank->driver_priv = psoc_eeprom_bank;
1041
1042 return ERROR_OK;
1043 }
1044
1045 static const struct command_registration psoc5lp_eeprom_exec_command_handlers[] = {
1046 COMMAND_REGISTRATION_DONE
1047 };
1048
1049 static const struct command_registration psoc5lp_eeprom_command_handlers[] = {
1050 {
1051 .name = "psoc5lp_eeprom",
1052 .mode = COMMAND_ANY,
1053 .help = "PSoC 5LP EEPROM command group",
1054 .usage = "",
1055 .chain = psoc5lp_eeprom_exec_command_handlers,
1056 },
1057 COMMAND_REGISTRATION_DONE
1058 };
1059
1060 struct flash_driver psoc5lp_eeprom_flash = {
1061 .name = "psoc5lp_eeprom",
1062 .commands = psoc5lp_eeprom_command_handlers,
1063 .flash_bank_command = psoc5lp_eeprom_flash_bank_command,
1064 .info = psoc5lp_eeprom_get_info_command,
1065 .probe = psoc5lp_eeprom_probe,
1066 .auto_probe = psoc5lp_eeprom_auto_probe,
1067 .protect_check = psoc5lp_eeprom_protect_check,
1068 .read = default_flash_read,
1069 .erase = psoc5lp_eeprom_erase,
1070 .erase_check = default_flash_blank_check,
1071 .write = psoc5lp_eeprom_write,
1072 .free_driver_priv = default_flash_free_driver_priv,
1073 };
1074
1075 /*
1076 * Program Flash
1077 */
1078
1079 struct psoc5lp_flash_bank {
1080 bool probed;
1081 const struct psoc5lp_device *device;
1082 bool ecc_enabled;
1083 /* If ecc is disabled, num_sectors counts both std and ecc sectors.
1084 * If ecc is enabled, num_sectors indicates just the number of std sectors.
1085 * However ecc sector descriptors bank->sector[num_sectors..2*num_sectors-1]
1086 * are used for driver private flash operations */
1087 };
1088
1089 static int psoc5lp_erase(struct flash_bank *bank, int first, int last)
1090 {
1091 struct psoc5lp_flash_bank *psoc_bank = bank->driver_priv;
1092 int i, retval;
1093
1094 if (!psoc_bank->ecc_enabled) {
1095 /* Silently avoid erasing sectors twice */
1096 if (last >= first + bank->num_sectors / 2) {
1097 LOG_DEBUG("Skipping duplicate erase of sectors %d to %d",
1098 first + bank->num_sectors / 2, last);
1099 last = first + (bank->num_sectors / 2) - 1;
1100 }
1101 /* Check for any remaining ECC sectors */
1102 if (last >= bank->num_sectors / 2) {
1103 LOG_WARNING("Skipping erase of ECC region sectors %d to %d",
1104 bank->num_sectors / 2, last);
1105 last = (bank->num_sectors / 2) - 1;
1106 }
1107 }
1108
1109 for (i = first; i <= last; i++) {
1110 retval = psoc5lp_spc_erase_sector(bank->target,
1111 i / SECTORS_PER_BLOCK, i % SECTORS_PER_BLOCK);
1112 if (retval != ERROR_OK)
1113 return retval;
1114 }
1115
1116 return ERROR_OK;
1117 }
1118
1119 /* Derived from core.c:default_flash_blank_check() */
1120 static int psoc5lp_erase_check(struct flash_bank *bank)
1121 {
1122 struct psoc5lp_flash_bank *psoc_bank = bank->driver_priv;
1123 struct target *target = bank->target;
1124 int i, retval;
1125
1126 if (target->state != TARGET_HALTED) {
1127 LOG_ERROR("Target not halted");
1128 return ERROR_TARGET_NOT_HALTED;
1129 }
1130
1131 int num_sectors = bank->num_sectors;
1132 if (psoc_bank->ecc_enabled)
1133 num_sectors *= 2; /* count both std and ecc sector always */
1134
1135 struct target_memory_check_block *block_array;
1136 block_array = malloc(num_sectors * sizeof(struct target_memory_check_block));
1137 if (block_array == NULL)
1138 return ERROR_FAIL;
1139
1140 for (i = 0; i < num_sectors; i++) {
1141 block_array[i].address = bank->base + bank->sectors[i].offset;
1142 block_array[i].size = bank->sectors[i].size;
1143 block_array[i].result = UINT32_MAX; /* erase state unknown */
1144 }
1145
1146 bool fast_check = true;
1147 for (i = 0; i < num_sectors; ) {
1148 retval = armv7m_blank_check_memory(target,
1149 block_array + i, num_sectors - i,
1150 bank->erased_value);
1151 if (retval < 1) {
1152 /* Run slow fallback if the first run gives no result
1153 * otherwise use possibly incomplete results */
1154 if (i == 0)
1155 fast_check = false;
1156 break;
1157 }
1158 i += retval; /* add number of blocks done this round */
1159 }
1160
1161 if (fast_check) {
1162 if (psoc_bank->ecc_enabled) {
1163 for (i = 0; i < bank->num_sectors; i++)
1164 bank->sectors[i].is_erased =
1165 (block_array[i].result != 1)
1166 ? block_array[i].result
1167 : block_array[i + bank->num_sectors].result;
1168 /* if std sector is erased, use status of ecc sector */
1169 } else {
1170 for (i = 0; i < num_sectors; i++)
1171 bank->sectors[i].is_erased = block_array[i].result;
1172 }
1173 retval = ERROR_OK;
1174 } else {
1175 LOG_ERROR("Can't run erase check - add working memory");
1176 retval = ERROR_FAIL;
1177 }
1178 free(block_array);
1179
1180 return retval;
1181 }
1182
1183 static int psoc5lp_write(struct flash_bank *bank, const uint8_t *buffer,
1184 uint32_t offset, uint32_t byte_count)
1185 {
1186 struct psoc5lp_flash_bank *psoc_bank = bank->driver_priv;
1187 struct target *target = bank->target;
1188 struct working_area *code_area, *even_row_area, *odd_row_area;
1189 uint32_t row_size;
1190 uint8_t temp[2], buf[12], ecc_bytes[ROW_ECC_SIZE];
1191 unsigned array_id, row;
1192 int i, retval;
1193
1194 if (offset + byte_count > bank->size) {
1195 LOG_ERROR("Writing to ECC not supported");
1196 return ERROR_FLASH_DST_OUT_OF_BANK;
1197 }
1198
1199 if (offset % ROW_SIZE != 0) {
1200 LOG_ERROR("Writes must be row-aligned, got offset 0x%08" PRIx32,
1201 offset);
1202 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
1203 }
1204
1205 row_size = ROW_SIZE;
1206 if (!psoc_bank->ecc_enabled) {
1207 row_size += ROW_ECC_SIZE;
1208 memset(ecc_bytes, bank->default_padded_value, ROW_ECC_SIZE);
1209 }
1210
1211 retval = psoc5lp_spc_get_temp(target, 3, temp);
1212 if (retval != ERROR_OK) {
1213 LOG_ERROR("Unable to read Die temperature");
1214 return retval;
1215 }
1216 LOG_DEBUG("Get_Temp: sign 0x%02" PRIx8 ", magnitude 0x%02" PRIx8,
1217 temp[0], temp[1]);
1218
1219 assert(target_get_working_area_avail(target) == target->working_area_size);
1220 retval = target_alloc_working_area(target,
1221 target_get_working_area_avail(target) / 2, &code_area);
1222 if (retval != ERROR_OK) {
1223 LOG_ERROR("Could not allocate working area for program SRAM");
1224 return retval;
1225 }
1226 assert(code_area->address < 0x20000000);
1227
1228 retval = target_alloc_working_area(target,
1229 SPC_OPCODE_LEN + 1 + row_size + 3 + SPC_OPCODE_LEN + 6,
1230 &even_row_area);
1231 if (retval != ERROR_OK) {
1232 LOG_ERROR("Could not allocate working area for even row");
1233 goto err_alloc_even;
1234 }
1235 assert(even_row_area->address >= 0x20000000);
1236
1237 retval = target_alloc_working_area(target, even_row_area->size,
1238 &odd_row_area);
1239 if (retval != ERROR_OK) {
1240 LOG_ERROR("Could not allocate working area for odd row");
1241 goto err_alloc_odd;
1242 }
1243 assert(odd_row_area->address >= 0x20000000);
1244
1245 for (array_id = offset / BLOCK_SIZE; byte_count > 0; array_id++) {
1246 for (row = (offset / ROW_SIZE) % ROWS_PER_BLOCK;
1247 row < ROWS_PER_BLOCK && byte_count > 0; row++) {
1248 bool even_row = (row % 2 == 0);
1249 struct working_area *data_area = even_row ? even_row_area : odd_row_area;
1250 unsigned len = MIN(ROW_SIZE, byte_count);
1251
1252 LOG_DEBUG("Writing load command for array %u row %u at 0x%08" TARGET_PRIxADDR,
1253 array_id, row, data_area->address);
1254
1255 psoc5lp_spc_write_opcode_buffer(target, buf, SPC_LOAD_ROW);
1256 buf[SPC_OPCODE_LEN] = array_id;
1257 retval = target_write_buffer(target, data_area->address, 4, buf);
1258 if (retval != ERROR_OK)
1259 goto err_write;
1260
1261 retval = target_write_buffer(target,
1262 data_area->address + SPC_OPCODE_LEN + 1,
1263 len, buffer);
1264 if (retval != ERROR_OK)
1265 goto err_write;
1266 buffer += len;
1267 byte_count -= len;
1268 offset += len;
1269
1270 if (len < ROW_SIZE) {
1271 uint8_t padding[ROW_SIZE];
1272
1273 memset(padding, bank->default_padded_value, ROW_SIZE);
1274
1275 LOG_DEBUG("Padding %d bytes", ROW_SIZE - len);
1276 retval = target_write_buffer(target,
1277 data_area->address + SPC_OPCODE_LEN + 1 + len,
1278 ROW_SIZE - len, padding);
1279 if (retval != ERROR_OK)
1280 goto err_write;
1281 }
1282
1283 if (!psoc_bank->ecc_enabled) {
1284 retval = target_write_buffer(target,
1285 data_area->address + SPC_OPCODE_LEN + 1 + ROW_SIZE,
1286 sizeof(ecc_bytes), ecc_bytes);
1287 if (retval != ERROR_OK)
1288 goto err_write;
1289 }
1290
1291 for (i = 0; i < 3; i++)
1292 buf[i] = 0x00; /* 3 NOPs for short delay */
1293 psoc5lp_spc_write_opcode_buffer(target, buf + 3, SPC_PRG_ROW);
1294 buf[3 + SPC_OPCODE_LEN] = array_id;
1295 buf[3 + SPC_OPCODE_LEN + 1] = row >> 8;
1296 buf[3 + SPC_OPCODE_LEN + 2] = row & 0xff;
1297 memcpy(buf + 3 + SPC_OPCODE_LEN + 3, temp, 2);
1298 buf[3 + SPC_OPCODE_LEN + 5] = 0x00; /* padding */
1299 retval = target_write_buffer(target,
1300 data_area->address + SPC_OPCODE_LEN + 1 + row_size,
1301 12, buf);
1302 if (retval != ERROR_OK)
1303 goto err_write;
1304
1305 retval = target_write_u32(target,
1306 even_row ? PHUB_CH0_BASIC_STATUS : PHUB_CH1_BASIC_STATUS,
1307 (even_row ? 0 : 1) << 8);
1308 if (retval != ERROR_OK)
1309 goto err_dma;
1310
1311 retval = target_write_u32(target,
1312 even_row ? PHUB_CH0_BASIC_CFG : PHUB_CH1_BASIC_CFG,
1313 PHUB_CHx_BASIC_CFG_WORK_SEP | PHUB_CHx_BASIC_CFG_EN);
1314 if (retval != ERROR_OK)
1315 goto err_dma;
1316
1317 retval = target_write_u32(target,
1318 even_row ? PHUB_CFGMEM0_CFG0 : PHUB_CFGMEM1_CFG0,
1319 PHUB_CFGMEMx_CFG0);
1320 if (retval != ERROR_OK)
1321 goto err_dma;
1322
1323 retval = target_write_u32(target,
1324 even_row ? PHUB_CFGMEM0_CFG1 : PHUB_CFGMEM1_CFG1,
1325 ((SPC_CPU_DATA >> 16) << 16) | (data_area->address >> 16));
1326 if (retval != ERROR_OK)
1327 goto err_dma;
1328
1329 retval = target_write_u32(target,
1330 even_row ? PHUB_TDMEM0_ORIG_TD0 : PHUB_TDMEM1_ORIG_TD0,
1331 PHUB_TDMEMx_ORIG_TD0_INC_SRC_ADDR |
1332 PHUB_TDMEMx_ORIG_TD0_NEXT_TD_PTR_LAST |
1333 ((SPC_OPCODE_LEN + 1 + row_size + 3 + SPC_OPCODE_LEN + 5) & 0xfff));
1334 if (retval != ERROR_OK)
1335 goto err_dma;
1336
1337 retval = target_write_u32(target,
1338 even_row ? PHUB_TDMEM0_ORIG_TD1 : PHUB_TDMEM1_ORIG_TD1,
1339 ((SPC_CPU_DATA & 0xffff) << 16) | (data_area->address & 0xffff));
1340 if (retval != ERROR_OK)
1341 goto err_dma;
1342
1343 retval = psoc5lp_spc_busy_wait_idle(target);
1344 if (retval != ERROR_OK)
1345 goto err_idle;
1346
1347 retval = target_write_u32(target,
1348 even_row ? PHUB_CH0_ACTION : PHUB_CH1_ACTION,
1349 PHUB_CHx_ACTION_CPU_REQ);
1350 if (retval != ERROR_OK)
1351 goto err_dma_action;
1352 }
1353 }
1354
1355 retval = psoc5lp_spc_busy_wait_idle(target);
1356
1357 err_dma_action:
1358 err_idle:
1359 err_dma:
1360 err_write:
1361 target_free_working_area(target, odd_row_area);
1362 err_alloc_odd:
1363 target_free_working_area(target, even_row_area);
1364 err_alloc_even:
1365 target_free_working_area(target, code_area);
1366
1367 return retval;
1368 }
1369
1370 static int psoc5lp_protect_check(struct flash_bank *bank)
1371 {
1372 struct psoc5lp_flash_bank *psoc_bank = bank->driver_priv;
1373 uint8_t row_data[ROW_SIZE];
1374 const unsigned protection_bytes_per_sector = ROWS_PER_SECTOR * 2 / 8;
1375 unsigned i, j, k, num_sectors;
1376 int retval;
1377
1378 if (bank->target->state != TARGET_HALTED) {
1379 LOG_ERROR("Target not halted");
1380 return ERROR_TARGET_NOT_HALTED;
1381 }
1382
1383 for (i = 0; i < DIV_ROUND_UP(bank->size, BLOCK_SIZE); i++) {
1384 retval = psoc5lp_spc_read_hidden_row(bank->target, i,
1385 SPC_ROW_PROTECTION, row_data);
1386 if (retval != ERROR_OK)
1387 return retval;
1388
1389 /* Last flash array may have less rows, but in practice full sectors. */
1390 if (i == bank->size / BLOCK_SIZE)
1391 num_sectors = (bank->size % BLOCK_SIZE) / SECTOR_SIZE;
1392 else
1393 num_sectors = SECTORS_PER_BLOCK;
1394
1395 for (j = 0; j < num_sectors; j++) {
1396 int sector_nr = i * SECTORS_PER_BLOCK + j;
1397 struct flash_sector *sector = &bank->sectors[sector_nr];
1398 struct flash_sector *ecc_sector;
1399
1400 if (psoc_bank->ecc_enabled)
1401 ecc_sector = &bank->sectors[bank->num_sectors + sector_nr];
1402 else
1403 ecc_sector = &bank->sectors[bank->num_sectors / 2 + sector_nr];
1404
1405 sector->is_protected = ecc_sector->is_protected = 0;
1406 for (k = protection_bytes_per_sector * j;
1407 k < protection_bytes_per_sector * (j + 1); k++) {
1408 assert(k < protection_bytes_per_sector * SECTORS_PER_BLOCK);
1409 LOG_DEBUG("row[%u][%02u] = 0x%02" PRIx8, i, k, row_data[k]);
1410 if (row_data[k] != 0x00) {
1411 sector->is_protected = ecc_sector->is_protected = 1;
1412 break;
1413 }
1414 }
1415 }
1416 }
1417
1418 return ERROR_OK;
1419 }
1420
1421 static int psoc5lp_get_info_command(struct flash_bank *bank, char *buf, int buf_size)
1422 {
1423 struct psoc5lp_flash_bank *psoc_bank = bank->driver_priv;
1424 char part_number[PART_NUMBER_LEN];
1425 const char *ecc;
1426
1427 psoc5lp_get_part_number(psoc_bank->device, part_number);
1428 ecc = psoc_bank->ecc_enabled ? "ECC enabled" : "ECC disabled";
1429
1430 snprintf(buf, buf_size, "%s %s", part_number, ecc);
1431
1432 return ERROR_OK;
1433 }
1434
1435 static int psoc5lp_probe(struct flash_bank *bank)
1436 {
1437 struct target *target = bank->target;
1438 struct psoc5lp_flash_bank *psoc_bank = bank->driver_priv;
1439 uint32_t flash_addr = bank->base;
1440 uint8_t nvl[4], temp[2];
1441 int i, retval;
1442
1443 if (target->state != TARGET_HALTED) {
1444 LOG_ERROR("Target not halted");
1445 return ERROR_TARGET_NOT_HALTED;
1446 }
1447
1448 if (!psoc_bank->device) {
1449 retval = psoc5lp_find_device(target, &psoc_bank->device);
1450 if (retval != ERROR_OK)
1451 return retval;
1452
1453 bank->size = psoc_bank->device->flash_kb * 1024;
1454 }
1455
1456 bank->num_sectors = DIV_ROUND_UP(bank->size, SECTOR_SIZE);
1457
1458 if (!psoc_bank->probed) {
1459 retval = psoc5lp_spc_enable_clock(target);
1460 if (retval != ERROR_OK)
1461 return retval;
1462
1463 /* First values read are inaccurate, so do it once now. */
1464 retval = psoc5lp_spc_get_temp(target, 3, temp);
1465 if (retval != ERROR_OK) {
1466 LOG_ERROR("Unable to read Die temperature");
1467 return retval;
1468 }
1469
1470 bank->sectors = calloc(bank->num_sectors * 2,
1471 sizeof(struct flash_sector));
1472 for (i = 0; i < bank->num_sectors; i++) {
1473 bank->sectors[i].size = SECTOR_SIZE;
1474 bank->sectors[i].offset = flash_addr - bank->base;
1475 bank->sectors[i].is_erased = -1;
1476 bank->sectors[i].is_protected = -1;
1477
1478 flash_addr += bank->sectors[i].size;
1479 }
1480 flash_addr = 0x48000000;
1481 for (i = bank->num_sectors; i < bank->num_sectors * 2; i++) {
1482 bank->sectors[i].size = ROWS_PER_SECTOR * ROW_ECC_SIZE;
1483 bank->sectors[i].offset = flash_addr - bank->base;
1484 bank->sectors[i].is_erased = -1;
1485 bank->sectors[i].is_protected = -1;
1486
1487 flash_addr += bank->sectors[i].size;
1488 }
1489
1490 bank->default_padded_value = bank->erased_value = 0x00;
1491
1492 psoc_bank->probed = true;
1493 }
1494
1495 retval = psoc5lp_spc_read_byte(target, SPC_ARRAY_NVL_USER, 3, &nvl[3]);
1496 if (retval != ERROR_OK)
1497 return retval;
1498 LOG_DEBUG("NVL[%d] = 0x%02" PRIx8, 3, nvl[3]);
1499 psoc_bank->ecc_enabled = nvl[3] & NVL_3_ECCEN;
1500
1501 if (!psoc_bank->ecc_enabled)
1502 bank->num_sectors *= 2;
1503
1504 return ERROR_OK;
1505 }
1506
1507 static int psoc5lp_auto_probe(struct flash_bank *bank)
1508 {
1509 return psoc5lp_probe(bank);
1510 }
1511
1512 COMMAND_HANDLER(psoc5lp_handle_mass_erase_command)
1513 {
1514 struct flash_bank *bank;
1515 int retval;
1516
1517 if (CMD_ARGC < 1)
1518 return ERROR_COMMAND_SYNTAX_ERROR;
1519
1520 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1521 if (retval != ERROR_OK)
1522 return retval;
1523
1524 retval = psoc5lp_spc_erase_all(bank->target);
1525 if (retval == ERROR_OK)
1526 command_print(CMD_CTX, "PSoC 5LP erase succeeded");
1527 else
1528 command_print(CMD_CTX, "PSoC 5LP erase failed");
1529
1530 return retval;
1531 }
1532
1533 FLASH_BANK_COMMAND_HANDLER(psoc5lp_flash_bank_command)
1534 {
1535 struct psoc5lp_flash_bank *psoc_bank;
1536
1537 psoc_bank = malloc(sizeof(struct psoc5lp_flash_bank));
1538 if (!psoc_bank)
1539 return ERROR_FLASH_OPERATION_FAILED;
1540
1541 psoc_bank->probed = false;
1542 psoc_bank->device = NULL;
1543
1544 bank->driver_priv = psoc_bank;
1545
1546 return ERROR_OK;
1547 }
1548
1549 static const struct command_registration psoc5lp_exec_command_handlers[] = {
1550 {
1551 .name = "mass_erase",
1552 .handler = psoc5lp_handle_mass_erase_command,
1553 .mode = COMMAND_EXEC,
1554 .usage = "bank_id",
1555 .help = "Erase all flash data and ECC/configuration bytes, "
1556 "all flash protection rows, "
1557 "and all row latches in all flash arrays on the device.",
1558 },
1559 COMMAND_REGISTRATION_DONE
1560 };
1561
1562 static const struct command_registration psoc5lp_command_handlers[] = {
1563 {
1564 .name = "psoc5lp",
1565 .mode = COMMAND_ANY,
1566 .help = "PSoC 5LP flash command group",
1567 .usage = "",
1568 .chain = psoc5lp_exec_command_handlers,
1569 },
1570 COMMAND_REGISTRATION_DONE
1571 };
1572
1573 struct flash_driver psoc5lp_flash = {
1574 .name = "psoc5lp",
1575 .commands = psoc5lp_command_handlers,
1576 .flash_bank_command = psoc5lp_flash_bank_command,
1577 .info = psoc5lp_get_info_command,
1578 .probe = psoc5lp_probe,
1579 .auto_probe = psoc5lp_auto_probe,
1580 .protect_check = psoc5lp_protect_check,
1581 .read = default_flash_read,
1582 .erase = psoc5lp_erase,
1583 .erase_check = psoc5lp_erase_check,
1584 .write = psoc5lp_write,
1585 .free_driver_priv = default_flash_free_driver_priv,
1586 };