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