1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * PSoC 5LP flash driver
6 * Copyright (c) 2016 Andreas Färber
14 #include <helper/time_support.h>
15 #include <target/armv7m.h>
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
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
43 #define PM_ACT_CFG12_EN_EE (1 << 4)
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
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
69 #define SPC_ROW_PROTECTION 0
71 #define SPC_OPCODE_LEN 3
73 #define SPC_SR_DATA_READY (1 << 0)
74 #define SPC_SR_IDLE (1 << 1)
76 #define PM_ACT_CFG0_EN_CLK_SPC (1 << 3)
78 #define PHUB_CHX_BASIC_CFG_EN (1 << 0)
79 #define PHUB_CHX_BASIC_CFG_WORK_SEP (1 << 5)
81 #define PHUB_CHX_ACTION_CPU_REQ (1 << 0)
83 #define PHUB_CFGMEMX_CFG0 (1 << 7)
85 #define PHUB_TDMEMX_ORIG_TD0_NEXT_TD_PTR_LAST (0xff << 16)
86 #define PHUB_TDMEMX_ORIG_TD0_INC_SRC_ADDR (1 << 24)
88 #define NVL_3_ECCEN (1 << 3)
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)
101 #define PART_NUMBER_LEN (17 + 1)
103 struct psoc5lp_device
{
112 * Device information collected from datasheets.
113 * Different temperature ranges (C/I/Q/A) may share IDs, not differing otherwise.
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 },
132 { .id
= 0x2E161069, .fam
= 8, .speed_mhz
= 80, .flash_kb
= 256, .eeprom_kb
= 2 },
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 },
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 },
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 },
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 },
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 },
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 },
190 static void psoc5lp_get_part_number(const struct psoc5lp_device
*dev
, char *str
)
192 strcpy(str
, "CY8Cabcdefg-LPxxx");
195 str
[5] = '0' + dev
->fam
;
197 switch (dev
->speed_mhz
) {
208 switch (dev
->flash_kb
) {
225 /* Package does not matter. */
229 /* Temperate range cannot uniquely be identified. */
233 static int psoc5lp_get_device_id(struct target
*target
, uint32_t *id
)
237 retval
= target_read_u32(target
, PANTHER_DEVICE_ID
, id
); /* dummy read */
238 if (retval
!= ERROR_OK
)
240 retval
= target_read_u32(target
, PANTHER_DEVICE_ID
, id
);
244 static int psoc5lp_find_device(struct target
*target
,
245 const struct psoc5lp_device
**device
)
253 retval
= psoc5lp_get_device_id(target
, &device_id
);
254 if (retval
!= ERROR_OK
)
256 LOG_DEBUG("PANTHER_DEVICE_ID = 0x%08" PRIX32
, device_id
);
258 for (i
= 0; i
< ARRAY_SIZE(psoc5lp_devices
); i
++) {
259 if (psoc5lp_devices
[i
].id
== device_id
) {
260 *device
= &psoc5lp_devices
[i
];
265 LOG_ERROR("Device 0x%08" PRIX32
" not supported", device_id
);
266 return ERROR_FLASH_OPER_UNSUPPORTED
;
269 static int psoc5lp_spc_enable_clock(struct target
*target
)
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");
280 if (pm_act_cfg0
& PM_ACT_CFG0_EN_CLK_SPC
)
281 return ERROR_OK
; /* clock already enabled */
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");
290 static int psoc5lp_spc_write_opcode(struct target
*target
, uint8_t opcode
)
294 retval
= target_write_u8(target
, SPC_CPU_DATA
, SPC_KEY1
);
295 if (retval
!= ERROR_OK
)
297 retval
= target_write_u8(target
, SPC_CPU_DATA
, SPC_KEY2
+ opcode
);
298 if (retval
!= ERROR_OK
)
300 retval
= target_write_u8(target
, SPC_CPU_DATA
, opcode
);
304 static void psoc5lp_spc_write_opcode_buffer(struct target
*target
,
305 uint8_t *buf
, uint8_t opcode
)
308 buf
[1] = SPC_KEY2
+ opcode
;
312 static int psoc5lp_spc_busy_wait_data(struct target
*target
)
318 retval
= target_read_u8(target
, SPC_SR
, &sr
); /* dummy read */
319 if (retval
!= ERROR_OK
)
322 endtime
= timeval_ms() + 1000; /* 1 second timeout */
325 retval
= target_read_u8(target
, SPC_SR
, &sr
);
326 if (retval
!= ERROR_OK
)
328 if (sr
== SPC_SR_DATA_READY
)
330 } while (timeval_ms() < endtime
);
332 return ERROR_FLASH_OPERATION_FAILED
;
335 static int psoc5lp_spc_busy_wait_idle(struct target
*target
)
341 retval
= target_read_u8(target
, SPC_SR
, &sr
); /* dummy read */
342 if (retval
!= ERROR_OK
)
345 endtime
= timeval_ms() + 1000; /* 1 second timeout */
348 retval
= target_read_u8(target
, SPC_SR
, &sr
);
349 if (retval
!= ERROR_OK
)
351 if (sr
== SPC_SR_IDLE
)
353 } while (timeval_ms() < endtime
);
355 return ERROR_FLASH_OPERATION_FAILED
;
358 static int psoc5lp_spc_load_byte(struct target
*target
,
359 uint8_t array_id
, uint8_t offset
, uint8_t value
)
363 retval
= psoc5lp_spc_write_opcode(target
, SPC_LOAD_BYTE
);
364 if (retval
!= ERROR_OK
)
366 retval
= target_write_u8(target
, SPC_CPU_DATA
, array_id
);
367 if (retval
!= ERROR_OK
)
369 retval
= target_write_u8(target
, SPC_CPU_DATA
, offset
);
370 if (retval
!= ERROR_OK
)
372 retval
= target_write_u8(target
, SPC_CPU_DATA
, value
);
373 if (retval
!= ERROR_OK
)
376 retval
= psoc5lp_spc_busy_wait_idle(target
);
377 if (retval
!= ERROR_OK
)
383 static int psoc5lp_spc_load_row(struct target
*target
,
384 uint8_t array_id
, const uint8_t *data
, unsigned row_size
)
389 retval
= psoc5lp_spc_write_opcode(target
, SPC_LOAD_ROW
);
390 if (retval
!= ERROR_OK
)
392 retval
= target_write_u8(target
, SPC_CPU_DATA
, array_id
);
393 if (retval
!= ERROR_OK
)
396 for (i
= 0; i
< row_size
; i
++) {
397 retval
= target_write_u8(target
, SPC_CPU_DATA
, data
[i
]);
398 if (retval
!= ERROR_OK
)
402 retval
= psoc5lp_spc_busy_wait_idle(target
);
403 if (retval
!= ERROR_OK
)
409 static int psoc5lp_spc_read_byte(struct target
*target
,
410 uint8_t array_id
, uint8_t offset
, uint8_t *data
)
414 retval
= psoc5lp_spc_write_opcode(target
, SPC_READ_BYTE
);
415 if (retval
!= ERROR_OK
)
417 retval
= target_write_u8(target
, SPC_CPU_DATA
, array_id
);
418 if (retval
!= ERROR_OK
)
420 retval
= target_write_u8(target
, SPC_CPU_DATA
, offset
);
421 if (retval
!= ERROR_OK
)
424 retval
= psoc5lp_spc_busy_wait_data(target
);
425 if (retval
!= ERROR_OK
)
428 retval
= target_read_u8(target
, SPC_CPU_DATA
, data
);
429 if (retval
!= ERROR_OK
)
432 retval
= psoc5lp_spc_busy_wait_idle(target
);
433 if (retval
!= ERROR_OK
)
439 static int psoc5lp_spc_write_row(struct target
*target
,
440 uint8_t array_id
, uint16_t row_id
, const uint8_t *temp
)
444 retval
= psoc5lp_spc_write_opcode(target
, SPC_WRITE_ROW
);
445 if (retval
!= ERROR_OK
)
447 retval
= target_write_u8(target
, SPC_CPU_DATA
, array_id
);
448 if (retval
!= ERROR_OK
)
450 retval
= target_write_u8(target
, SPC_CPU_DATA
, row_id
>> 8);
451 if (retval
!= ERROR_OK
)
453 retval
= target_write_u8(target
, SPC_CPU_DATA
, row_id
& 0xff);
454 if (retval
!= ERROR_OK
)
456 retval
= target_write_u8(target
, SPC_CPU_DATA
, temp
[0]);
457 if (retval
!= ERROR_OK
)
459 retval
= target_write_u8(target
, SPC_CPU_DATA
, temp
[1]);
460 if (retval
!= ERROR_OK
)
463 retval
= psoc5lp_spc_busy_wait_idle(target
);
464 if (retval
!= ERROR_OK
)
470 static int psoc5lp_spc_write_user_nvl(struct target
*target
,
475 retval
= psoc5lp_spc_write_opcode(target
, SPC_WRITE_USER_NVL
);
476 if (retval
!= ERROR_OK
)
478 retval
= target_write_u8(target
, SPC_CPU_DATA
, array_id
);
479 if (retval
!= ERROR_OK
)
482 retval
= psoc5lp_spc_busy_wait_idle(target
);
483 if (retval
!= ERROR_OK
)
489 static int psoc5lp_spc_erase_sector(struct target
*target
,
490 uint8_t array_id
, uint8_t row_id
)
494 retval
= psoc5lp_spc_write_opcode(target
, SPC_ERASE_SECTOR
);
495 if (retval
!= ERROR_OK
)
497 retval
= target_write_u8(target
, SPC_CPU_DATA
, array_id
);
498 if (retval
!= ERROR_OK
)
500 retval
= target_write_u8(target
, SPC_CPU_DATA
, row_id
);
501 if (retval
!= ERROR_OK
)
504 retval
= psoc5lp_spc_busy_wait_idle(target
);
505 if (retval
!= ERROR_OK
)
511 static int psoc5lp_spc_erase_all(struct target
*target
)
515 retval
= psoc5lp_spc_write_opcode(target
, SPC_ERASE_ALL
);
516 if (retval
!= ERROR_OK
)
519 retval
= psoc5lp_spc_busy_wait_idle(target
);
520 if (retval
!= ERROR_OK
)
526 static int psoc5lp_spc_read_hidden_row(struct target
*target
,
527 uint8_t array_id
, uint8_t row_id
, uint8_t *data
)
531 retval
= psoc5lp_spc_write_opcode(target
, SPC_READ_HIDDEN_ROW
);
532 if (retval
!= ERROR_OK
)
534 retval
= target_write_u8(target
, SPC_CPU_DATA
, array_id
);
535 if (retval
!= ERROR_OK
)
537 retval
= target_write_u8(target
, SPC_CPU_DATA
, row_id
);
538 if (retval
!= ERROR_OK
)
541 retval
= psoc5lp_spc_busy_wait_data(target
);
542 if (retval
!= ERROR_OK
)
545 for (i
= 0; i
< ROW_SIZE
; i
++) {
546 retval
= target_read_u8(target
, SPC_CPU_DATA
, &data
[i
]);
547 if (retval
!= ERROR_OK
)
551 retval
= psoc5lp_spc_busy_wait_idle(target
);
552 if (retval
!= ERROR_OK
)
558 static int psoc5lp_spc_get_temp(struct target
*target
, uint8_t samples
,
563 retval
= psoc5lp_spc_write_opcode(target
, SPC_GET_TEMP
);
564 if (retval
!= ERROR_OK
)
566 retval
= target_write_u8(target
, SPC_CPU_DATA
, samples
);
567 if (retval
!= ERROR_OK
)
570 retval
= psoc5lp_spc_busy_wait_data(target
);
571 if (retval
!= ERROR_OK
)
574 retval
= target_read_u8(target
, SPC_CPU_DATA
, &data
[0]);
575 if (retval
!= ERROR_OK
)
577 retval
= target_read_u8(target
, SPC_CPU_DATA
, &data
[1]);
578 if (retval
!= ERROR_OK
)
581 retval
= psoc5lp_spc_busy_wait_idle(target
);
582 if (retval
!= ERROR_OK
)
588 static int psoc5lp_spc_read_volatile_byte(struct target
*target
,
589 uint8_t array_id
, uint8_t offset
, uint8_t *data
)
593 retval
= psoc5lp_spc_write_opcode(target
, SPC_READ_VOLATILE_BYTE
);
594 if (retval
!= ERROR_OK
)
596 retval
= target_write_u8(target
, SPC_CPU_DATA
, array_id
);
597 if (retval
!= ERROR_OK
)
599 retval
= target_write_u8(target
, SPC_CPU_DATA
, offset
);
600 if (retval
!= ERROR_OK
)
603 retval
= psoc5lp_spc_busy_wait_data(target
);
604 if (retval
!= ERROR_OK
)
607 retval
= target_read_u8(target
, SPC_CPU_DATA
, data
);
608 if (retval
!= ERROR_OK
)
611 retval
= psoc5lp_spc_busy_wait_idle(target
);
612 if (retval
!= ERROR_OK
)
622 struct psoc5lp_nvl_flash_bank
{
624 const struct psoc5lp_device
*device
;
627 static int psoc5lp_nvl_read(struct flash_bank
*bank
,
628 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
632 retval
= psoc5lp_spc_enable_clock(bank
->target
);
633 if (retval
!= ERROR_OK
)
637 retval
= psoc5lp_spc_read_byte(bank
->target
,
638 SPC_ARRAY_NVL_USER
, offset
, buffer
);
639 if (retval
!= ERROR_OK
)
649 static int psoc5lp_nvl_erase(struct flash_bank
*bank
, unsigned int first
,
652 LOG_WARNING("There is no erase operation for NV Latches");
653 return ERROR_FLASH_OPER_UNSUPPORTED
;
656 static int psoc5lp_nvl_erase_check(struct flash_bank
*bank
)
658 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++)
659 bank
->sectors
[i
].is_erased
= 0;
664 static int psoc5lp_nvl_write(struct flash_bank
*bank
,
665 const uint8_t *buffer
, uint32_t offset
, uint32_t byte_count
)
667 struct target
*target
= bank
->target
;
668 uint8_t *current_data
, val
;
669 bool write_required
= false, pullup_needed
= false, ecc_changed
= false;
673 if (offset
!= 0 || byte_count
!= bank
->size
) {
674 LOG_ERROR("NVL can only be written in whole");
675 return ERROR_FLASH_OPER_UNSUPPORTED
;
678 current_data
= calloc(1, bank
->size
);
681 retval
= psoc5lp_nvl_read(bank
, current_data
, offset
, byte_count
);
682 if (retval
!= ERROR_OK
) {
686 for (i
= offset
; i
< byte_count
; i
++) {
687 if (current_data
[i
] != buffer
[i
]) {
688 write_required
= true;
692 if (((buffer
[2] & 0x80) == 0x80) && ((current_data
[0] & 0x0C) != 0x08))
693 pullup_needed
= true;
694 if (((buffer
[3] ^ current_data
[3]) & 0x08) == 0x08)
698 if (!write_required
) {
699 LOG_INFO("Unchanged, skipping NVL write");
703 retval
= target_read_u8(target
, PRT1_PC2
, &val
);
704 if (retval
!= ERROR_OK
)
708 retval
= target_write_u8(target
, PRT1_PC2
, val
);
709 if (retval
!= ERROR_OK
)
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
)
719 retval
= psoc5lp_spc_read_volatile_byte(target
,
720 SPC_ARRAY_NVL_USER
, i
, &val
);
721 if (retval
!= ERROR_OK
)
723 if (val
!= buffer
[i
]) {
724 LOG_ERROR("Failed to load NVL byte %" PRIu32
": "
725 "expected 0x%02" PRIx8
", read 0x%02" PRIx8
,
727 return ERROR_FLASH_OPERATION_FAILED
;
731 retval
= psoc5lp_spc_write_user_nvl(target
, SPC_ARRAY_NVL_USER
);
732 if (retval
!= ERROR_OK
)
736 retval
= target_call_reset_callbacks(target
, RESET_INIT
);
737 if (retval
!= ERROR_OK
)
738 LOG_WARNING("Reset failed after enabling or disabling ECC");
744 static int psoc5lp_nvl_get_info_command(struct flash_bank
*bank
,
745 struct command_invocation
*cmd
)
747 struct psoc5lp_nvl_flash_bank
*psoc_nvl_bank
= bank
->driver_priv
;
748 char part_number
[PART_NUMBER_LEN
];
750 psoc5lp_get_part_number(psoc_nvl_bank
->device
, part_number
);
752 command_print_sameline(cmd
, "%s", part_number
);
757 static int psoc5lp_nvl_probe(struct flash_bank
*bank
)
759 struct psoc5lp_nvl_flash_bank
*psoc_nvl_bank
= bank
->driver_priv
;
762 if (psoc_nvl_bank
->probed
)
765 if (bank
->target
->state
!= TARGET_HALTED
) {
766 LOG_ERROR("Target not halted");
767 return ERROR_TARGET_NOT_HALTED
;
770 retval
= psoc5lp_find_device(bank
->target
, &psoc_nvl_bank
->device
);
771 if (retval
!= ERROR_OK
)
774 bank
->base
= NVL_META_BASE
;
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;
784 psoc_nvl_bank
->probed
= true;
789 static int psoc5lp_nvl_auto_probe(struct flash_bank
*bank
)
791 struct psoc5lp_nvl_flash_bank
*psoc_nvl_bank
= bank
->driver_priv
;
793 if (psoc_nvl_bank
->probed
)
796 return psoc5lp_nvl_probe(bank
);
799 FLASH_BANK_COMMAND_HANDLER(psoc5lp_nvl_flash_bank_command
)
801 struct psoc5lp_nvl_flash_bank
*psoc_nvl_bank
;
803 psoc_nvl_bank
= malloc(sizeof(struct psoc5lp_nvl_flash_bank
));
805 return ERROR_FLASH_OPERATION_FAILED
;
807 psoc_nvl_bank
->probed
= false;
809 bank
->driver_priv
= psoc_nvl_bank
;
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
,
831 struct psoc5lp_eeprom_flash_bank
{
833 const struct psoc5lp_device
*device
;
836 static int psoc5lp_eeprom_erase(struct flash_bank
*bank
, unsigned int first
,
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
)
851 static int psoc5lp_eeprom_write(struct flash_bank
*bank
,
852 const uint8_t *buffer
, uint32_t offset
, uint32_t byte_count
)
854 struct target
*target
= bank
->target
;
859 if (offset
% EEPROM_ROW_SIZE
!= 0) {
860 LOG_ERROR("Writes must be row-aligned, got offset 0x%08" PRIx32
,
862 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
865 retval
= psoc5lp_spc_get_temp(target
, 3, temp
);
866 if (retval
!= ERROR_OK
) {
867 LOG_ERROR("Unable to read Die temperature");
870 LOG_DEBUG("Get_Temp: sign 0x%02" PRIx8
", magnitude 0x%02" PRIx8
,
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
)
879 retval
= psoc5lp_spc_write_row(target
, SPC_ARRAY_EEPROM
,
881 if (retval
!= ERROR_OK
)
884 buffer
+= EEPROM_ROW_SIZE
;
885 byte_count
-= EEPROM_ROW_SIZE
;
886 offset
+= EEPROM_ROW_SIZE
;
888 if (byte_count
> 0) {
889 uint8_t buf
[EEPROM_ROW_SIZE
];
891 memcpy(buf
, buffer
, byte_count
);
892 memset(buf
+ byte_count
, bank
->default_padded_value
,
893 EEPROM_ROW_SIZE
- byte_count
);
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
)
901 retval
= psoc5lp_spc_write_row(target
, SPC_ARRAY_EEPROM
,
903 if (retval
!= ERROR_OK
)
910 static int psoc5lp_eeprom_get_info_command(struct flash_bank
*bank
, struct command_invocation
*cmd
)
912 struct psoc5lp_eeprom_flash_bank
*psoc_eeprom_bank
= bank
->driver_priv
;
913 char part_number
[PART_NUMBER_LEN
];
915 psoc5lp_get_part_number(psoc_eeprom_bank
->device
, part_number
);
917 command_print_sameline(cmd
, "%s", part_number
);
922 static int psoc5lp_eeprom_probe(struct flash_bank
*bank
)
924 struct psoc5lp_eeprom_flash_bank
*psoc_eeprom_bank
= bank
->driver_priv
;
925 uint32_t flash_addr
= bank
->base
;
929 if (psoc_eeprom_bank
->probed
)
932 if (bank
->target
->state
!= TARGET_HALTED
) {
933 LOG_ERROR("Target not halted");
934 return ERROR_TARGET_NOT_HALTED
;
937 retval
= psoc5lp_find_device(bank
->target
, &psoc_eeprom_bank
->device
);
938 if (retval
!= ERROR_OK
)
941 retval
= target_read_u32(bank
->target
, PM_ACT_CFG12
, &val
);
942 if (retval
!= ERROR_OK
)
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
)
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;
961 flash_addr
+= bank
->sectors
[i
].size
;
964 bank
->default_padded_value
= bank
->erased_value
= 0x00;
966 psoc_eeprom_bank
->probed
= true;
971 static int psoc5lp_eeprom_auto_probe(struct flash_bank
*bank
)
973 struct psoc5lp_eeprom_flash_bank
*psoc_eeprom_bank
= bank
->driver_priv
;
975 if (psoc_eeprom_bank
->probed
)
978 return psoc5lp_eeprom_probe(bank
);
981 FLASH_BANK_COMMAND_HANDLER(psoc5lp_eeprom_flash_bank_command
)
983 struct psoc5lp_eeprom_flash_bank
*psoc_eeprom_bank
;
985 psoc_eeprom_bank
= malloc(sizeof(struct psoc5lp_eeprom_flash_bank
));
986 if (!psoc_eeprom_bank
)
987 return ERROR_FLASH_OPERATION_FAILED
;
989 psoc_eeprom_bank
->probed
= false;
990 psoc_eeprom_bank
->device
= NULL
;
992 bank
->driver_priv
= psoc_eeprom_bank
;
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
,
1014 struct psoc5lp_flash_bank
{
1016 const struct psoc5lp_device
*device
;
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 */
1024 static int psoc5lp_erase(struct flash_bank
*bank
, unsigned int first
,
1027 struct psoc5lp_flash_bank
*psoc_bank
= bank
->driver_priv
;
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;
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;
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
)
1055 /* Derived from core.c:default_flash_blank_check() */
1056 static int psoc5lp_erase_check(struct flash_bank
*bank
)
1058 struct psoc5lp_flash_bank
*psoc_bank
= bank
->driver_priv
;
1059 struct target
*target
= bank
->target
;
1062 if (target
->state
!= TARGET_HALTED
) {
1063 LOG_ERROR("Target not halted");
1064 return ERROR_TARGET_NOT_HALTED
;
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 */
1071 struct target_memory_check_block
*block_array
;
1072 block_array
= malloc(num_sectors
* sizeof(struct target_memory_check_block
));
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 */
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
);
1088 /* Run slow fallback if the first run gives no result
1089 * otherwise use possibly incomplete results */
1094 i
+= retval
; /* add number of blocks done this round */
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 */
1106 for (unsigned int i
= 0; i
< num_sectors
; i
++)
1107 bank
->sectors
[i
].is_erased
= block_array
[i
].result
;
1111 LOG_ERROR("Can't run erase check - add working memory");
1112 retval
= ERROR_FAIL
;
1119 static int psoc5lp_write(struct flash_bank
*bank
, const uint8_t *buffer
,
1120 uint32_t offset
, uint32_t byte_count
)
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
;
1126 uint8_t temp
[2], buf
[12], ecc_bytes
[ROW_ECC_SIZE
];
1127 unsigned array_id
, row
;
1130 if (offset
+ byte_count
> bank
->size
) {
1131 LOG_ERROR("Writing to ECC not supported");
1132 return ERROR_FLASH_DST_OUT_OF_BANK
;
1135 if (offset
% ROW_SIZE
!= 0) {
1136 LOG_ERROR("Writes must be row-aligned, got offset 0x%08" PRIx32
,
1138 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
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
);
1147 retval
= psoc5lp_spc_get_temp(target
, 3, temp
);
1148 if (retval
!= ERROR_OK
) {
1149 LOG_ERROR("Unable to read Die temperature");
1152 LOG_DEBUG("Get_Temp: sign 0x%02" PRIx8
", magnitude 0x%02" PRIx8
,
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");
1162 assert(code_area
->address
< 0x20000000);
1164 retval
= target_alloc_working_area(target
,
1165 SPC_OPCODE_LEN
+ 1 + row_size
+ 3 + SPC_OPCODE_LEN
+ 6,
1167 if (retval
!= ERROR_OK
) {
1168 LOG_ERROR("Could not allocate working area for even row");
1169 goto err_alloc_even
;
1171 assert(even_row_area
->address
>= 0x20000000);
1173 retval
= target_alloc_working_area(target
, even_row_area
->size
,
1175 if (retval
!= ERROR_OK
) {
1176 LOG_ERROR("Could not allocate working area for odd row");
1179 assert(odd_row_area
->address
>= 0x20000000);
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
);
1188 LOG_DEBUG("Writing load command for array %u row %u at " TARGET_ADDR_FMT
,
1189 array_id
, row
, data_area
->address
);
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
)
1197 retval
= target_write_buffer(target
,
1198 data_area
->address
+ SPC_OPCODE_LEN
+ 1,
1200 if (retval
!= ERROR_OK
)
1206 if (len
< ROW_SIZE
) {
1207 uint8_t padding
[ROW_SIZE
];
1209 memset(padding
, bank
->default_padded_value
, ROW_SIZE
);
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
)
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
)
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
,
1238 if (retval
!= ERROR_OK
)
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
)
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
)
1253 retval
= target_write_u32(target
,
1254 even_row
? PHUB_CFGMEM0_CFG0
: PHUB_CFGMEM1_CFG0
,
1256 if (retval
!= ERROR_OK
)
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
)
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
)
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
)
1279 retval
= psoc5lp_spc_busy_wait_idle(target
);
1280 if (retval
!= ERROR_OK
)
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
;
1291 retval
= psoc5lp_spc_busy_wait_idle(target
);
1297 target_free_working_area(target
, odd_row_area
);
1299 target_free_working_area(target
, even_row_area
);
1301 target_free_working_area(target
, code_area
);
1306 static int psoc5lp_protect_check(struct flash_bank
*bank
)
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
;
1314 if (bank
->target
->state
!= TARGET_HALTED
) {
1315 LOG_ERROR("Target not halted");
1316 return ERROR_TARGET_NOT_HALTED
;
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
)
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
;
1329 num_sectors
= SECTORS_PER_BLOCK
;
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
;
1336 if (psoc_bank
->ecc_enabled
)
1337 ecc_sector
= &bank
->sectors
[bank
->num_sectors
+ sector_nr
];
1339 ecc_sector
= &bank
->sectors
[bank
->num_sectors
/ 2 + sector_nr
];
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;
1357 static int psoc5lp_get_info_command(struct flash_bank
*bank
, struct command_invocation
*cmd
)
1359 struct psoc5lp_flash_bank
*psoc_bank
= bank
->driver_priv
;
1360 char part_number
[PART_NUMBER_LEN
];
1363 psoc5lp_get_part_number(psoc_bank
->device
, part_number
);
1364 ecc
= psoc_bank
->ecc_enabled
? "ECC enabled" : "ECC disabled";
1366 command_print_sameline(cmd
, "%s %s", part_number
, ecc
);
1371 static int psoc5lp_probe(struct flash_bank
*bank
)
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];
1379 if (target
->state
!= TARGET_HALTED
) {
1380 LOG_ERROR("Target not halted");
1381 return ERROR_TARGET_NOT_HALTED
;
1384 if (!psoc_bank
->device
) {
1385 retval
= psoc5lp_find_device(target
, &psoc_bank
->device
);
1386 if (retval
!= ERROR_OK
)
1389 bank
->size
= psoc_bank
->device
->flash_kb
* 1024;
1392 bank
->num_sectors
= DIV_ROUND_UP(bank
->size
, SECTOR_SIZE
);
1394 if (!psoc_bank
->probed
) {
1395 retval
= psoc5lp_spc_enable_clock(target
);
1396 if (retval
!= ERROR_OK
)
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");
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;
1414 flash_addr
+= bank
->sectors
[i
].size
;
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;
1423 flash_addr
+= bank
->sectors
[i
].size
;
1426 bank
->default_padded_value
= bank
->erased_value
= 0x00;
1428 psoc_bank
->probed
= true;
1431 retval
= psoc5lp_spc_read_byte(target
, SPC_ARRAY_NVL_USER
, 3, &nvl
[3]);
1432 if (retval
!= ERROR_OK
)
1434 LOG_DEBUG("NVL[%d] = 0x%02" PRIx8
, 3, nvl
[3]);
1435 psoc_bank
->ecc_enabled
= nvl
[3] & NVL_3_ECCEN
;
1437 if (!psoc_bank
->ecc_enabled
)
1438 bank
->num_sectors
*= 2;
1443 static int psoc5lp_auto_probe(struct flash_bank
*bank
)
1445 return psoc5lp_probe(bank
);
1448 COMMAND_HANDLER(psoc5lp_handle_mass_erase_command
)
1450 struct flash_bank
*bank
;
1454 return ERROR_COMMAND_SYNTAX_ERROR
;
1456 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1457 if (retval
!= ERROR_OK
)
1460 retval
= psoc5lp_spc_erase_all(bank
->target
);
1461 if (retval
== ERROR_OK
)
1462 command_print(CMD
, "PSoC 5LP erase succeeded");
1464 command_print(CMD
, "PSoC 5LP erase failed");
1469 FLASH_BANK_COMMAND_HANDLER(psoc5lp_flash_bank_command
)
1471 struct psoc5lp_flash_bank
*psoc_bank
;
1473 psoc_bank
= malloc(sizeof(struct psoc5lp_flash_bank
));
1475 return ERROR_FLASH_OPERATION_FAILED
;
1477 psoc_bank
->probed
= false;
1478 psoc_bank
->device
= NULL
;
1480 bank
->driver_priv
= psoc_bank
;
1485 static const struct command_registration psoc5lp_exec_command_handlers
[] = {
1487 .name
= "mass_erase",
1488 .handler
= psoc5lp_handle_mass_erase_command
,
1489 .mode
= COMMAND_EXEC
,
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.",
1495 COMMAND_REGISTRATION_DONE
1498 static const struct command_registration psoc5lp_command_handlers
[] = {
1501 .mode
= COMMAND_ANY
,
1502 .help
= "PSoC 5LP flash command group",
1504 .chain
= psoc5lp_exec_command_handlers
,
1506 COMMAND_REGISTRATION_DONE
1509 const struct flash_driver psoc5lp_flash
= {
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
,